Programmatically create machine startup script in local Group Policy: script executes but is not visible in Group Policy Editor

5,817

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 both CR+LF and LF 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.

Code requires PsIni module which can be installed by Install-Module -Name PsIni

#Requires -Module psIni

$scriptsConfig = @{
    StartExecutePSFirst = 'true'
    EndExecutePSFirst =   'true'
}
$startup = @{
    '0CmdLine' =    'AllUsersStartup.ps1'
    '0Parameters' = ''
}
$newIniContent = [ordered] @{ 
    ScriptsConfig = $scriptsConfig
    Startup =       $startup 
}
$newIniContent | Out-IniFile -filePath C:\Windows\System32\GroupPolicy\Machine\Scripts\psScripts.ini -encoding Unicode -force
Share:
5,817

Related videos on Youtube

maoizm
Author by

maoizm

all bugs can be derived by a highly constrained form of problem solving acting on incomplete data

Updated on September 18, 2022

Comments

  • maoizm
    maoizm over 1 year

    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:

    screenshot of Group Policy Editor

    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
      }
    
    • JosefZ
      JosefZ almost 6 years
      Check scripts.ini and psscripts.ini in C:\Windows\System32\GroupPolicy\Machine\Scripts rather than registry.
    • maoizm
      maoizm almost 6 years
      @JosefZ thanks, I had no clue about psScripts.ini. After googling found good explanation hexacorn.com/blog/2017/01/07/beyond-good-ol-run-key-part-52 how to deal with this file