Guest User

Untitled

a guest
Feb 20th, 2021
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.02 KB | None | 0 0
  1. <#
  2. .SYNOPSIS
  3. Pin pre-configured shortcuts to Start
  4.  
  5. .PARAMETER ControlPanel
  6. Pin the "Control Panel" shortcut to Start
  7.  
  8. .PARAMETER DevicesPrinters
  9. Pin the "Devices & Printers" shortcut to Start
  10.  
  11. .PARAMETER PowerShell
  12. Pin the "Windows PowerShell" shortcut to Start
  13.  
  14. .EXAMPLE
  15. PinToStart -Tiles ControlPanel, DevicesPrinters, PowerShell
  16.  
  17. .NOTES
  18. Current user
  19. #>
  20. function PinToStart
  21. {
  22. [CmdletBinding()]
  23. param
  24. (
  25. [Parameter(Mandatory = $true)]
  26. [ValidateSet("ControlPanel", "DevicesPrinters", "PowerShell")]
  27. [string[]]
  28. $Tiles
  29. )
  30.  
  31. # Extract string from shell32.dll using its' number
  32. # https://github.com/Disassembler0/Win10-Initial-Setup-Script/issues/8#issue-227159084
  33. $Signature = @{
  34. Namespace = "WinAPI"
  35. Name = "GetStr"
  36. Language = "CSharp"
  37. MemberDefinition = @"
  38. [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  39. public static extern IntPtr GetModuleHandle(string lpModuleName);
  40. [DllImport("user32.dll", CharSet = CharSet.Auto)]
  41. internal static extern int LoadString(IntPtr hInstance, uint uID, StringBuilder lpBuffer, int nBufferMax);
  42. public static string GetString(uint strId)
  43. {
  44. IntPtr intPtr = GetModuleHandle("shell32.dll");
  45. StringBuilder sb = new StringBuilder(255);
  46. LoadString(intPtr, strId, sb, sb.Capacity);
  47. return sb.ToString();
  48. }
  49. "@
  50. }
  51. if (-not ("WinAPI.GetStr" -as [type]))
  52. {
  53. Add-Type @Signature -Using System.Text
  54. }
  55.  
  56. # Extract the "Devices and Printers" string from shell32.dll
  57. $DevicesPrinters = [WinAPI.GetStr]::GetString(30493)
  58.  
  59. # Create the old-style "Devices and Printers" shortcut in the Start menu
  60. $Shell = New-Object -ComObject Wscript.Shell
  61. $Shortcut = $Shell.CreateShortcut("$env:APPDATA\Microsoft\Windows\Start menu\Programs\System Tools\$DevicesPrinters.lnk")
  62. $Shortcut.TargetPath = "control"
  63. $Shortcut.Arguments = "printers"
  64. $Shortcut.IconLocation = "$env:SystemRoot\system32\DeviceCenter.dll"
  65. $Shortcut.Save()
  66.  
  67. Start-Sleep -Seconds 3
  68.  
  69. # Export the current Start layout
  70. $StartLayout = "$PSScriptRoot\StartLayout.xml"
  71. Export-StartLayout -Path $StartLayout -UseDesktopApplicationID
  72.  
  73. $Parameters = @(
  74. # Control Panel hash table
  75. @{
  76. # Special name for Control Panel
  77. Name = "ControlPanel"
  78. Size = "2x2"
  79. Column = 0
  80. Row = 0
  81. AppID = "Microsoft.Windows.ControlPanel"
  82. },
  83. # "Devices & Printers" hash table
  84. @{
  85. # Special name for "Devices & Printers"
  86. Name = "DevicesPrinters"
  87. Size = "2x2"
  88. Column = 2
  89. Row = 0
  90. AppID = "Microsoft.AutoGenerated.{7FF3FDB0-CFD9-F944-4722-A9E766EDE23F}"
  91. },
  92. # Windows PowerShell hash table
  93. @{
  94. # Special name for Windows PowerShell
  95. Name = "PowerShell"
  96. Size = "2x2"
  97. Column = 4
  98. Row = 0
  99. AppID = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe"
  100. }
  101. )
  102.  
  103. # Valid columns to place tiles in
  104. $ValidColumns = @(0, 2, 4)
  105. [string]$StartLayoutNS = "http://schemas.microsoft.com/Start/2014/StartLayout"
  106.  
  107. # Add pre-configured hastable to XML
  108. function Add-Tile
  109. {
  110. param
  111. (
  112. [string]
  113. $Size,
  114.  
  115. [int]
  116. $Column,
  117.  
  118. [int]
  119. $Row,
  120.  
  121. [string]
  122. $AppID
  123. )
  124.  
  125. [string]$elementName = "start:DesktopApplicationTile"
  126. [Xml.XmlElement]$Table = $xml.CreateElement($elementName, $StartLayoutNS)
  127. $Table.SetAttribute("Size", $Size)
  128. $Table.SetAttribute("Column", $Column)
  129. $Table.SetAttribute("Row", $Row)
  130. $Table.SetAttribute("DesktopApplicationID", $AppID)
  131.  
  132. $Table
  133. }
  134.  
  135. [xml]$xXML. = Get-Content -Path $StartLayout -Encoding UTF8 -Force
  136.  
  137. foreach ($Tile in $Tiles)
  138. {
  139. $Parameter = $Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}
  140. $Group = $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.Group | Where-Object -FilterScript {$_.Name -eq "Sophia Script"}
  141.  
  142. # If "Sophia Script" group exists in Start
  143. if ($Group)
  144. {
  145. $DesktopApplicationID = ($Parameters | Where-Object -FilterScript {$_.Name -eq $Tile}).AppID
  146.  
  147. if (-not ($Group.DesktopApplicationTile | Where-Object -FilterScript {$_.DesktopApplicationID -eq $DesktopApplicationID}))
  148. {
  149. # Calculate current filled columns
  150. $CurrentColumns = @($Group.DesktopApplicationTile.Column)
  151. # Calculate current free columns and take the first one
  152. $Column = (Compare-Object -ReferenceObject $ValidColumns -DifferenceObject $CurrentColumns).InputObject | Select-Object -First 1
  153. # If filled cells contain desired ones assign the first free cell
  154. if ($CurrentColumns -contains $Parameter.Column)
  155. {
  156. $Parameter.Column = $Column
  157. }
  158. $Group.AppendChild((Add-Tile @Parameter)) | Out-Null
  159. }
  160. }
  161. else
  162. { # Create the "Sophia Script" group
  163. [Xml.XmlElement]$Group = $XML.CreateElement("start:Group", $StartLayoutNS)
  164. $Group.SetAttribute("Name","Sophia Script")
  165. $Group.AppendChild((Add-Tile @Parameter)) | Out-Null
  166. $XML.LayoutModificationTemplate.DefaultLayoutOverride.StartLayoutCollection.StartLayout.AppendChild($Group) | Out-Null
  167. }
  168. }
  169.  
  170. $XML.Save($StartLayout)
  171.  
  172. # Temporarily disable changing the Start menu layout
  173. if (-not (Test-Path -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer))
  174. {
  175. New-Item -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Force
  176. }
  177. New-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Value 1 -Force
  178. New-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Value $StartLayout -Force
  179.  
  180. Start-Sleep -Seconds 3
  181.  
  182. # Restart the Start menu
  183. Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
  184.  
  185. Start-Sleep -Seconds 3
  186.  
  187. # Enable changing the Start menu layout
  188. Remove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name LockedStartLayout -Force -ErrorAction Ignore
  189. Remove-ItemProperty -Path HKCU:\SOFTWARE\Policies\Microsoft\Windows\Explorer -Name StartLayoutFile -Force -ErrorAction Ignore
  190.  
  191. Get-Item -Path $StartLayout | Remove-Item -Force -ErrorAction Ignore
  192.  
  193. Stop-Process -Name StartMenuExperienceHost -Force -ErrorAction Ignore
  194.  
  195. Start-Sleep -Seconds 3
  196. }
Add Comment
Please, Sign In to add comment