-->

Is there any way to programmatically add a startup

2019-06-24 07:52发布

问题:

I need to write a script that can add itself to the startup scripts in the local group policy so that it can run even when no users are logged in. This can be done using gpedit.msc and going into Computer Configuration > Windows Settings > Scripts > Startup. However, I haven't found a way to do this programmatically.

I've looked into simply editing the registry. I found the relevant location to be HKLM\Software\Microsoft\Windows\CurrentVersion\Group Policy\State\Machine\Scripts\Startup, but simply adding my own entry does not have any effect. The computer is not part of a domain.

Does anyone know how to do this? Is there a WMI approach?

回答1:

I think you have to modify %windir%\system32\GroupPolicy\gpt.ini, appending [{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}] to the gPCMachineExtensionNames line and incrementing the Version value by one. (source).

Try adding and removing a script via group policy editor and you can watch how gpt.ini changes. When you add a script, you can also use the structure created in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\Scripts\Startup\0 as a template.

For anyone coming across this thread whose machine is a member of a domain, I've noticed that domain-defined group policies appear in the registry after local policies. So if you've already got a domain policy at ...\Scripts\Startup\0, you should copy it to ...\Scripts\Startup\1 before creating your local machine policy.

In any case, expirement with the GUI and see how stuff changes before attempting programmatically.

You'll also need to run gpupdate to refresh group policies.



回答2:

I am working on a script for this and my testing shows you do not have to edit the registry at all. Follow these steps and it will work

  1. Find the last script number in scripts.ini (There are two lines for each script "0CmdLine=" and "0Parameters=".
  2. Add two lines for each of your scripts to be added (e.g. "1CmdLine=myscript.vbs" and "1Parameters="
  3. Increment the "version=" number in gpt.ini
  4. Run Gpupdate to apply it

Important Note for scripting a solution: gpt.ini uses UTF-8 encoding, scripts.ini uses Unicode. Cheers M$!

Hope this helps people.

Shaun



回答3:

Just configure it manually on one machine and run gpupdate /force. Then copy %systemroot%\System32\GroupPolicy from your source machine to %systemroot%\System32\GroupPolicy on the rest of your machines.



回答4:

even though it's an older post, i think people might still be looking for the same scenario (as was i).

please find below a batch of mine for extending the scripts.ini.
you only need 2 or 3 parameters, example at the end of the script.

also, keep in mind to edit the gpt.ini if required!
more information on the gpt.ini here
easiest way to determine the GUIDs is to edit in gpedit.msc and watch the changes.

please be careful with the script and test it before use in productive environment!

@echo off
setlocal enabledelayedexpansion

REM get parameter for scripts.ini changes
if not "%~1"=="" (
set type=%1
) else (
goto enderror
)
if not "%~2"=="" (
set cmd=%2
) else (
goto enderror
)
if not "%~3"=="" (
set params=%3
) else (
set params=
)

if not exist scripts.ini echo. 2>scripts.ini

if exist scripts.ini (
set ctr=0

for /f %%a in (scripts.ini) do (
    echo %%a | findstr /C:"[Logon]" 1>nul
    if not errorlevel 1 (
    set /a ctr+=1
    )
)
if !ctr!==0 (
    echo [Logon]>>scripts.ini
)

set ctr=0

for /f %%a in (scripts.ini) do (
    echo %%a | findstr /C:"[Logoff]" 1>nul
    if not errorlevel 1 (
    set /a ctr+=1
    )
)
if !ctr!==0 (
    echo [Logoff]>>scripts.ini
)
)

REM remove scripts-new.ini if exists
if exist scripts-new.ini (
del /F /Q scripts-new.ini
)

REM ctr = number at front for each cmd-param pair - subctr = counter for lines --> pairs - diff = change from Logon to Logoff or vice versa
set ctr=0
set subctr=0
set diff=0
set used=0

for /f %%a in (scripts.ini) do (
set line=%%a

echo !line! | findstr /C:"[Logoff]" 1>nul
if not errorlevel 1 (
    if !diff!==1 goto endlogon
)

echo !line! | findstr "CmdLine=!cmd!" 1>nul
if not errorlevel 1 (
    set /a used+=1
)

if !diff!==1 (
echo !ctr!!line:~1!>>scripts-new.ini
set /a subctr+=1
if !subctr!==2 (
    set /a ctr+=1
    set subctr=0
)
)

echo !line! | findstr /C:"[Logon]" 1>nul
if not errorlevel 1 (
    set diff=1
    echo !line!>>scripts-new.ini
)
)

:endlogon

if /I !type!==logon if !used!==0 (
    echo !ctr!CmdLine=!cmd!>>scripts-new.ini
    echo !ctr!Parameters=!params!>>scripts-new.ini
)

set ctr=0
set diff=0
set used=0

for /f %%a in (scripts.ini) do (
set line=%%a

echo !line! | findstr /C:"[Logon]" 1>nul
if not errorlevel 1 (
    if !diff!==1 goto endlogoff
)

echo !line! | findstr "CmdLine=!cmd!" 1>nul
if not errorlevel 1 (
    set /a used+=1
)

if !diff!==1 (
echo !ctr!!line:~1!>>scripts-new.ini
set /a subctr+=1
if !subctr!==2 (
    set /a ctr+=1
    set subctr=0
)
)

echo !line! | findstr /C:"[Logoff]" 1>nul
if not errorlevel 1 (
    set diff=1
    echo !line!>>scripts-new.ini
)
)

:endlogoff

if /I !type!==logoff if !used!==0 (
    echo !ctr!CmdLine=!cmd!>>scripts-new.ini
    echo !ctr!Parameters=!params!>>scripts-new.ini
)

goto end

:enderror
echo Usage: scripts-extender.bat [LOGON ^| LOGOFF] [Script Name] "[optional Parameters for Script - WITH QUOTES!]"
echo Example: scripts-externder.bat logon netlogon.bat "param1 param2"

:end
move /Y scripts.ini scripts-old.ini
move /Y scripts-new.ini scripts.ini