update stuff

This commit is contained in:
abrown38 committed 2025-04-14 18:07:11 +01:00
1 parent c679ff2f09
commit dbaafbbb38
5 files changed
+188 -4

No files matched your search

+1
View File
@@ -3,3 +3,4 @@
- import_tasks: chocolatey.yml
- import_tasks: rdgw.yml
- import_tasks: start_menu.yml
- import_tasks: update.yml
@@ -7,7 +7,7 @@
- name: Copy start menu to workbench VMs
win_copy:
src: "workbench.xml"
dest: "C:\\eidf\\{{ win_project }}.xml"
dest: "{{ start_menu_xml }}"
force: true
when: inventory_hostname in groups['meta-variant_workbench']
when: groups['meta-variant_workbench'] is defined
@@ -20,7 +20,7 @@
- name: Copy start menu to application VMs
win_copy:
src: "application.xml"
dest: "C:\\eidf\\{{ win_project }}.xml"
dest: "{{ start_menu_xml }}"
force: true
when: inventory_hostname in groups['meta-variant_application']
when: groups['meta-variant_application'] is defined
@@ -33,7 +33,7 @@
- name: Copy start menu to gpu VMs
win_copy:
src: "gpu.xml"
dest: "C:\\eidf\\{{ win_project }}.xml"
dest: "{{ start_menu_xml }}"
force: true
when: inventory_hostname in groups['meta-variant_gpu']
when: groups['meta-variant_gpu'] is defined
+33
View File
@@ -0,0 +1,33 @@
---
- name: Install all updates and reboot as many times as needed
tags: update_windows
ansible.windows.win_updates:
category_names: '*'
reboot: true
- name: Update all choco packages
win_command: choco upgrade all -y
tags: update_choco
- name: Update Start Menu Shortcuts in XML on remote Windows machines
tags: update_start_menu
block:
- name: Copy Python script to target machine
ansible.windows.win_template:
src: "{{ script_name }}"
dest: "{{ script_path }}"
force: true
- name: Copy current XML to backup location
win_copy:
remote_src: true
src: "{{ start_menu_xml }}"
dest: "{{ backup_xml }}"
- name: Run Python script on remote machine
win_command: python "{{ script_path }}"
register: output
- name: debug
debug:
var: output
@@ -0,0 +1,146 @@
import os
import shutil
import re
import xml.etree.ElementTree as ET
original_xml = "{{ start_menu_xml }}"
backup_xml = "{{ backup_xml }}"
# This script assumes backup and copying already handled by Ansible
START_MENU_PATHS = {
"%ALLUSERSPROFILE%\\Microsoft\\Windows\\Start Menu\\Programs": os.path.expandvars(r"%ALLUSERSPROFILE%\Microsoft\Windows\Start Menu\Programs")
}
def extract_version(filename):
match = re.search(r'(\d+\.\d+\.\d+|\d+)', filename)
if match:
return tuple(map(int, match.group(0).split('.')))
return (0,)
def adjust_app_name(app_name):
return f"{app_name} " if len(app_name) == 1 else app_name
def remove_bracketed_text(filename):
return re.sub(r"[\(\[].*?[\)\]]", "", filename).strip()
def folder_has_standalone_version(folder_name):
return bool(re.search(r'\b\d+(?:\.\d+){1,3}\b', folder_name))
def clean_folder_name(folder_name):
return re.sub(r'\b\d+(?:\.\d+){1,3}\b', '', folder_name).strip()
def remove_version_number(app_name):
if re.search(r'\d+\.\d+(\.\d+)*$', app_name):
return re.sub(r'(\s*\d+\.\d+(\.\d+)*\s*)$', '', app_name).strip()
return app_name
def is_extra_word_present(filename, base_name):
name_without_ext = os.path.splitext(filename)[0].lower()
return name_without_ext != base_name.lower()
def version_sort_key(filename, base_name):
version = extract_version(filename)
cleaned_name = remove_bracketed_text(filename)
padded_version = version + (0,) * (3 - len(version))
return (
is_extra_word_present(filename, base_name),
len(cleaned_name),
-padded_version[0],
-padded_version[1] if len(padded_version) > 1 else 0,
-padded_version[2] if len(padded_version) > 2 else 0
)
def get_clean_base_name(app_name):
return re.sub(r"(\s*\d+(\.\d+)*\s*)+$", "", app_name).strip()
def find_best_match(app_name, available_files):
base_name = get_clean_base_name(app_name)
adjusted_name = adjust_app_name(base_name)
start_matches = [file for file in available_files if file.lower().startswith(adjusted_name.lower())]
exact_match = [f for f in start_matches if os.path.splitext(f)[0].lower() == adjusted_name.lower()]
if exact_match:
print(f"Exact match for {app_name}: {exact_match[0]}")
return exact_match[0]
best = min(start_matches, key=lambda f: version_sort_key(f, adjusted_name)) if start_matches else None
print(f"Best match for {app_name}: {best}")
return best
def convert_to_env_path(abs_path):
for env_path, abs_root in START_MENU_PATHS.items():
if abs_path.startswith(abs_root):
return abs_path.replace(abs_root, env_path)
return abs_path
def find_shortcut_paths(app_names):
app_paths = {}
all_lnk_files = {}
for _, start_menu in START_MENU_PATHS.items():
for root, _, files in os.walk(start_menu):
for file in files:
if file.endswith(".lnk"):
full_path = os.path.join(root, file)
all_lnk_files[file] = full_path
for app_name in app_names:
best_match = find_best_match(app_name, all_lnk_files.keys())
if best_match:
env_path = convert_to_env_path(all_lnk_files[best_match])
app_paths[app_name] = env_path
print(f"Mapped {app_name} to {env_path}")
else:
print(f"No match found for {app_name}")
return app_paths
def extract_app_names_and_paths(xml_file):
tree = ET.parse(xml_file)
root = tree.getroot()
apps = {}
for tile in root.findall(".//{*}DesktopApplicationTile"):
link_path = tile.get("DesktopApplicationLinkPath")
if link_path:
folder_name = os.path.basename(os.path.dirname(link_path))
lnk_name = os.path.splitext(os.path.basename(link_path))[0]
if folder_has_standalone_version(folder_name):
app_name = clean_folder_name(folder_name)
else:
app_name = remove_bracketed_text(lnk_name)
app_name = remove_version_number(app_name)
app_name = adjust_app_name(app_name)
apps[app_name] = link_path
print(f"Extracted {app_name} from {link_path}")
return apps
def update_xml_paths(xml_file, old_new_paths):
with open(xml_file, "r", encoding="utf-8") as file:
content = file.read()
for old_path, new_path in old_new_paths:
content = content.replace(old_path, new_path)
print(f"Replaced {old_path} with {new_path}")
with open(xml_file, "w", encoding="utf-8") as file:
file.write(content)
print("Start menu XML updated successfully.")
if __name__ == "__main__":
xml_file = original_xml
extracted_apps_with_paths = extract_app_names_and_paths(xml_file)
app_shortcuts = find_shortcut_paths(extracted_apps_with_paths.keys())
old_new_paths = []
for app_name, old_path in extracted_apps_with_paths.items():
new_path = app_shortcuts.get(app_name)
if new_path:
old_new_paths.append((old_path, new_path))
else:
print(f"Warning: No new path found for {app_name}. Keeping old path.")
update_xml_paths(xml_file, old_new_paths)
+5 -1
View File
@@ -1 +1,5 @@
repo_url: 'http://{{ win_project }}-choc.{{ win_project }}.loc/chocolatey'
repo_url: 'http://{{ win_project }}-choc.{{ win_project }}.loc/chocolatey'
start_menu_xml: "C:\\eidf\\{{ win_project }}.xml"
backup_xml: "C:\\eidf\\{{ win_project }}-old.xml"
script_name: newXML.py
script_path: "C:\\eidf\\{{ script_name }}"