Update: I am now attempting to use a Get-StartApps command instead of recursively going through the files with a filter. Now I am in need of help re-writing the logic behind the insert sections noted in #3 below. Any suggestions would be amazing!
I found and have been working with a series of scripts that can be used to create a start menu XML. The version I have settled on is below. Unfortunately, I cannot seem to get it to handle ".URL",".Website", ".shortcut" extensions.
I have tried the following (one at a time and together):
- On line 90 removing the -filter "*.lnk"
- Adding -filter ".website", -Filter ".shortcut"... to line 90
Creating ifelse statements for each of these extensions modeled after lines 107-116
if ($SoftwareLinks.Name -like "$Software.lnk") { $SoftwareLink = $SoftwareLinks | where {$_ -like "$Software.lnk"} $child = $StartMenuXml.CreateElement("start","DesktopApplicationTile","http://schemas.microsoft.com/Start/2014/StartLayout") if ($SoftwareLink.FullName.GetType().BaseType -eq [System.Array]) { ## If multiple links, use the first one $child.SetAttribute('DesktopApplicationLinkPath',$SoftwareLink.FullName[0]) } else { $child.SetAttribute('DesktopApplicationLinkPath',$SoftwareLink.FullName) } }
None of this seems to work when trying to pick up links that are placed in the start menu folder. Has anyone come across this? Do you have any advice on how to fix this? Whole script below:
# Where to save start menu xml
#$StartMenuFile = "$ENV:programfiles\DESKTOPENGINEERING\startmenu\startmenu.xml"
$StartMenuFile = "$ENV:programfiles\DESKTOPENGINEERING\startmenu\startmenu.xml"
#$OldStartMenuFile = "$ENV:programfiles\DESKTOPENGINEERING\startmenu\startmenu.xml"
$OldStartMenuFile = "$programfiles\DESKTOPENGINEERING\startmenu\startmenu.old"
# Set this to SilentlyContinue for no debug, or Continue for debug output
$DebugPreference = "SilentlyContinue"
# Remove old startmenu.old file
IF (Test-path $OldStartMenuFile) {
Write-Debug "The file `"$OldStartMenuFile`" already exists and will be removed!"
Remove-item $OldStartMenuFile -Force
} Else {
Write-Debug "The file `"$OldStartMenuFile`" does not exist! Lets move along then..."
}
# Rename startmenu.xml to startmenu.old
IF (Test-path $StartMenuFile) {
Write-Debug "renaming file `"$OldStartMenuFile`"..."
Rename-Item -Path $StartMenuFile -NewName $OldStartMenuFile -Force
} Else {
Write-Debug "The file `"$OldStartMenuFile`" does not exist! Lets move along then..."
}
# One last check to see if file exists or not
IF (Test-path $StartMenuFile) {
Write-Error "Could not rename `"$OldStartMenuFile`", script aborted"
Break
} Else {
Write-Debug "The file `"$OldStartMenuFile`" does not exist! Lets move along then..."
}
# Make sure folder exist and halt if it can't be created
$StartMenuFolder=(Split-path -parent $StartMenuFile)
IF (Test-path $StartMenuFolder) { } ELSE { New-Item -ItemType Directory -Path $StartMenuFolder }
IF (Test-path $StartMenuFolder) { } ELSE { Write-Error "Could not create `"$StartMenuFolder`", script aborted" ; Break }
# Specify number of cols in startmenu
$NumCol = 6
# Add the new group in $MenuGroups
# Format: "order. group title" = "list of Software Links", "Followed by other links"
$MenuGroups = @{
"1. Internet & Network tools" = "Microsoft.MicrosoftEdge_8wekyb3d8bbwe!MicrosoftEdge"
"2. Microsoft Office" = "Access 2016","Excel 2016","Outlook 2016","PowerPoint 2016","Project 2016","Publisher 2016","Word 2016"
"3. Text, file & programming tools" = "Calculator","Notepad"
"4. Media tools" = "Paint"
"5. Scientific software" = "Calculator"
"6. Administrator" = "Powershell"
"7. Other tools" = "Google Chrome", "Google Link"
}
# Building up base startmenu xml
[xml]$StartMenuXml = '<LayoutModificationTemplate
xmlns="http://schemas.microsoft.com/Start/2014/LayoutModification"
xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout"
xmlns:start="http://schemas.microsoft.com/Start/2014/StartLayout"
xmlns:taskbar="http://schemas.microsoft.com/Start/2014/TaskbarLayout"
Version="1">
<LayoutOptions StartTileGroupsColumnCount="1" StartTileGroupCellWidth="'+$NumCol+'" />
<DefaultLayoutOverride LayoutCustomizationRestrictionType="OnlySpecifiedGroups">
<StartLayoutCollection>
<defaultlayout:StartLayout GroupCellWidth="'+$NumCol+'" xmlns:defaultlayout="http://schemas.microsoft.com/Start/2014/FullDefaultLayout">
</defaultlayout:StartLayout>
</StartLayoutCollection>
</DefaultLayoutOverride>
<CustomTaskbarLayoutCollection PinListPlacement="Replace">
<defaultlayout:TaskbarLayout>
<taskbar:TaskbarPinList>
<taskbar:UWA AppUserModelID="Microsoft.WindowsCalculator_8wekyb3d8bbwe!App"/>
</taskbar:TaskbarPinList>
</defaultlayout:TaskbarLayout>
</CustomTaskbarLayoutCollection>
</LayoutModificationTemplate>'
# Selecting XML element where all software will be placed
$DefaultLayoutElement = $StartMenuXml.GetElementsByTagName("defaultlayout:StartLayout")
# Fetching all software links on start menu
$SoftwareLinks = Get-ChildItem "$env:PROGRAMDATA\Microsoft\Windows\Start Menu" -recurse -filter "*.lnk"
# Looping all menu groups defined above
foreach ($MenuGroup in $MenuGroups.Keys | Sort-Object) {
# Init xml element for software group
$SoftwareGroupXml = $StartMenuXml.CreateElement("start","Group", "http://schemas.microsoft.com/Start/2014/StartLayout")
$SoftwareGroupXml.SetAttribute('Name',$MenuGroup.Substring(3))
# Init row and col
$col = 0
$row = 0
# Looping all software links in start menu
foreach ($Software in $MenuGroups[$MenuGroup]) {
# Check if it is time for a new col
if (($col%($NumCol-1) -eq 1) -and ($col -ne 1)) {
$row +=1
$col = 0
}
# Check if specified software is found in start menu. If so, add software element
if ($SoftwareLinks.Name -like "$Software.lnk") {
$SoftwareLink = $SoftwareLinks | where {$_ -like "$Software.lnk"}
$child = $StartMenuXml.CreateElement("start","DesktopApplicationTile","http://schemas.microsoft.com/Start/2014/StartLayout")
if ($SoftwareLink.FullName.GetType().BaseType -eq [System.Array]) { ## If multiple links, use the first one
$child.SetAttribute('DesktopApplicationLinkPath',$SoftwareLink.FullName[0])
} else {
$child.SetAttribute('DesktopApplicationLinkPath',$SoftwareLink.FullName)
}
}
# Or check if Microsoft app is specified. If so add app element
elseif ($Software -like "Microsoft.*!*") {
$child = $StartMenuXml.CreateElement("start","Tile","http://schemas.microsoft.com/Start/2014/StartLayout")
$child.SetAttribute('AppUserModelID',$Software)
}
# Add common attributes is software or app is found and append xml element
if (($child.HasAttributes) -and (($Software -like "Microsoft.*!*") -or ($SoftwareLinks.Name -like "$Software.lnk"))) {
$child.SetAttribute('Size','2x2')
$child.SetAttribute('Column',$col)
$child.SetAttribute('Row',$row)
$SoftwareGroupXml.AppendChild($child) | Out-Null
$col +=1
}
}
# If a software group is not null, add it!
if ($SoftwareGroupXml.HasChildNodes) {
$DefaultLayoutElement.AppendChild($SoftwareGroupXml) | Out-Null
}
}
# Save to file
$StartMenuXml.Save($StartMenuFile)### Script ends ###