Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Pin pre-configured shortcuts to Start
- .PARAMETER ControlPanel
- Pin the "Control Panel" shortcut to Start
- .PARAMETER DevicesPrinters
- Pin the "Devices & Printers" shortcut to Start
- .PARAMETER PowerShell
- Pin the "Windows PowerShell" shortcut to Start
- .EXAMPLE
- PinToStart -Tiles ControlPanel, DevicesPrinters, PowerShell
- .NOTES
- Current user
- #>
- function PinToStart
- {
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true)]
- [ValidateSet("ControlPanel", "DevicesPrinters", "PowerShell")]
- [string[]]
- $Tiles
- )
- # Extract string from shell32.dll using its' number
- # https://github.com/Disassembler0/Win10-Initial-Setup-Script/issues/8#issue-227159084
- $Signature = @{
- Namespace = "WinAPI"
- Name = "GetStr"
- Language = "CSharp"
- MemberDefinition = @"
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public static extern IntPtr GetModuleHandle(string lpModuleName);
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
- public static string GetString(uint strId)
- {
- IntPtr intPtr = GetModuleHandle("shell32.dll");
- StringBuilder sb = new StringBuilder(255);
- LoadString(intPtr, strId, sb, sb.Capacity);
- return sb.ToString();
- }
- "@
- }
- if (-not ("WinAPI.GetStr" -as [type]))
- {
- Add-Type @Signature -Using System.Text
- }
- # Extract the "Devices and Printers" string from shell32.dll
- $DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
- # Create the old-style "Devices and Printers" shortcut in the Start menu
- $Shell = New-Object -ComObject Wscript.Shell
- $Shortcut = $Shell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start menu\Programs\System Tools\$DevicesPrinters.lnk")
- $Shortcut.TargetPath = "control"
- $Shortcut.Arguments = "printers"
- $Shortcut.IconLocation = "$env:SystemRoot\system32\DeviceCenter.dll"
- $Shortcut.Save()
- Start-Sleep -Seconds 3
- # Export the current Start layout
- $StartLayout = "$PSScriptRoot\StartLayout.xml"
- Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
- $Parameters = @(
- # Control Panel hash table
- @{
- # Special name for Control Panel
- Name = "ControlPanel"
- Size = "2x2"
- Column = 0
- Row = 0
- AppID = "Microsoft.Windows.ControlPanel"
- },
- # "Devices & Printers" hash table
- @{
- # Special name for "Devices & Printers"
- Name = "DevicesPrinters"
- Size = "2x2"
- Column = 2
- Row = 0
- AppID = "Microsoft.AutoGenerated.{7FF3FDB0-CFD9-F944-4722-A9E766EDE23F}"
- },
- # Windows PowerShell hash table
- @{
- # Special name for Windows PowerShell
- Name = "PowerShell"
- Size = "2x2"
- Column = 4
- Row = 0
- AppID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe"
- }
- )
- # Valid columns to place tiles in
- $ValidColumns = @(0, 2, 4)
- [string]$StartLayoutNS = "http://schemas.microsoft.com/Start/2014/StartLayout"
- # Add pre-configured hastable to XML
- function Add-Tile
- {
- param
- (
- [string]
- $Size,
- [int]
- $Column,
- [int]
- $Row,
- [string]
- $AppID
- )
- [string]$elementName = "start:DesktopApplicationTile"
- [Xml.XmlElement]$Table = $xml.CreateElement($elementName, $StartLayoutNS)
- $Table.SetAttribute("Size", $Size)
- $Table.SetAttribute("Column", $Column)
- $Table.SetAttribute("Row", $Row)
- $Table.SetAttribute("DesktopApplicationID", $AppID)
- $Table
- }
- [xml]$xXML. = Get-Content -Path $StartLayout -Encoding UTF8 -Force
- foreach ($Tile in $Tiles)
- {
- $Parameter = $Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}
- $Group = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group | Where-Object -FilterScript {$_.Name -eq "Sophia Script"}
- # If "Sophia Script" group exists in Start
- if ($Group)
- {
- $DesktopApplicationID = ($Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}).AppID
- if (-not ($Group.DesktopApplicationTile | Where-Object -FilterScript {$_.DesktopApplicationID -eq $DesktopApplicationID}))
- {
- # Calculate current filled columns
- $CurrentColumns = @($Group.DesktopApplicationTile.Column)
- # Calculate current free columns and take the first one
- $Column = (Compare-Object -ReferenceObject $ValidColumns -DifferenceObject $CurrentColumns).InputObject | Select-Object -First 1
- # If filled cells contain desired ones assign the first free cell
- if ($CurrentColumns -contains $Parameter.Column)
- {
- $Parameter.Column = $Column
- }
- $Group.AppendChild((Add-Tile @Parameter)) | Out-Null
- }
- }
- else
- { # Create the "Sophia Script" group
- [Xml.XmlElement]$Group = $XML.CreateElement("start:Group", $StartLayoutNS)
- $Group.SetAttribute("Name","Sophia Script")
- $Group.AppendChild((Add-Tile @Parameter)) | Out-Null
- $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.AppendChild($Group) | Out-Null
- }
- }
- $XML.Save($StartLayout)
- # Temporarily disable changing the Start menu layout
- if (-not (Test-Path -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer))
- {
- New-Item -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Force
- }
- New-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Value 1 -Force
- New-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Value $StartLayout -Force
- Start-Sleep -Seconds 3
- # Restart the Start menu
- Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
- Start-Sleep -Seconds 3
- # Enable changing the Start menu layout
- Remove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Force -ErrorAction Ignore
- Remove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Force -ErrorAction Ignore
- Get-Item -Path $StartLayout | Remove-Item -Force -ErrorAction Ignore
- Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
- Start-Sleep -Seconds 3
- }
Add Comment
Please, Sign In to add comment