I have managed to programmatically create machine startup Powershell script for Windows 10 Pro and place it in the local Group Policy (see below a powershell script used for creation of startup script).
Just to reiterate: I am using local Group Policy and my computer is not in a Domain.
Startup script logs its execution in the Event Log and everything goes perfectly as I see appropriate events in the log.
Problem
When I open local Group Policy Editor (gpedit.msc
) and look into Computer startup scripts there are no any scripts registered as you can see from the screenshot:
The script itself is correctly placed in the directory for Group Policy scripts (C:\Windows\System32\GroupPolicy\Machine\Scripts\Startup
)
Powershell script used for creation of the machine startup script in local Group Policy
$path = "$ENV:systemRoot\System32\GroupPolicy\Machine\Scripts\Startup"
if (-not (Test-Path $path)) {
New-Item -path $path -itemType Directory
}
'Write-EventLog -LogName xxx -source Scripts -EntryType Information -EventId 2 -Message "Execute machine startup script: $psCommandPath"' |
Out-File -filePath "$path\AllUsersStartup.ps1" -encoding ascii
# Add script to Group Policy through the Registry
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0\0' |
ForEach-Object {
if (-not (Test-Path $_)) {
New-Item -path $_ -force
}
}
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0' |
ForEach-Object {
New-ItemProperty -path "$_" -name DisplayName -propertyType String -value "Local Group Policy"
New-ItemProperty -path "$_" -name FileSysPath -propertyType String -value "$ENV:systemRoot\System32\GroupPolicy\Machine"
New-ItemProperty -path "$_" -name GPO-ID -propertyType String -value "LocalGPO"
New-ItemProperty -path "$_" -name GPOName -propertyType String -value "Local Group Policy"
New-ItemProperty -path "$_" -name PSScriptOrder -propertyType DWord -value 2
New-ItemProperty -path "$_" -name SOM-ID -propertyType String -value "Local"
}
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0\0',
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup\0\0' |
ForEach-Object {
New-ItemProperty -path "$_" -name Script -propertyType String -value 'AllUsersStartup.ps1'
New-ItemProperty -path "$_" -name Parameters -propertyType String -value ''
New-ItemProperty -path "$_" -name IsPowershell -propertyType DWord -value 1
New-ItemProperty -path "$_" -name ExecTime -propertyType QWord -value 0
}
Best Answer
It turns out that local Group Policy Editor gets the list and order of scripts not only from the Registry but also from
C:\Windows\System32\GroupPolicy\Machine\Scripts\psScripts.ini
. This is almost usual .ini file with some weird features: it should be in UTF-16LE BOM format and can be with bothCR
+LF
andLF
line endings (which is rather strange for Windows).Below you'll find a piece of code to write correct
psScripts.ini
for adding machine startup script to local Group Policy.