Automatically Scripting Windows Startup Scripts and Shutdown Scripts using the Command Line

System Requirements:

  • Windows 2000, XP Professional, Vista Business, 7 Professional, 7 Enterprise, 8 Professional, 8 Enterprise, 8.1 Professional, 8.1 Enterprise, 10 Professional, 10 Enterprise
  • Windows Server 2000, 2003, 2008, 2008 R2, 2012, 2012 R2, 2016
  • Windows Scripting Host 5.8 or higher

The Problem:

It’s been a problem since 1999. You want to install a Startup or Shutdown Script on a local Windows machine without having to go through GPEdit.msc to manually populate the user interface necessary to install the script processing hook.

Well, now you can do it automatically!

More Info

So here is a VBScript api file which does the work for you to install either a Startup or Shutdown script from the command line. This installs the script as part of the Local Windows Group Policy processor, which on Domain Joined systems will be executed before Domain Logon Scripts.

  • No warranty is offered or implied. Use this script at your own risk
  • Please do not redistribute this script, please link to this page [Perma-link: http://www.c-amie.co.uk/qlink/?id=142]
  • You may not sell or profit from the use of this script
  • You may not bundle this script as part of an application deliverable or payload
If you found this useful, please consider making a donation or using the Amazon Affiliates Link to help support this site!

Download: AddLocalGpStartupScript.zip [4KB]

Usage

You can call the script from the Command Line or a bat (batch) file using the following syntax

cscript.exe AddLocalGpStartupScript.vbs <startup|shutdown> <path> <arguments>

You can view the help screen and examples at any time by calling

cscript.exe AddLocalGpStartupScript.vbs /?

Examples

Writes http://www.c-amie.co.uk/ to the file C:\LogFile.log during startup

cscript.exe AddLocalGpStartupScript.vbs startup "cmd.exe" "/c echo http://www.c-amie.co.uk>>C:\LogFile.log"

Opens C:\LogFile.log in Notepad during shutdown

cscript.exe AddLocalGpStartupScript.vbs shutdown "notepad.exe" "C:\LogFile.log"

Calls D:\Scripts\MyScript.cmd with no arguments during shutdown

cscript.exe AddLocalGpStartupScript.vbs shutdown "D:\Scripts\MyScript.cmd"

Executes the PowerShell Script C:\MyPsScript.ps1, ignoring the System Execution Policy during startup

cscript.exe AddLocalGpStartupScript.vbs startup "powershell.exe" "-ExecutionPolicy bypass -windowstyle hidden -file C:\MyPsScript.ps1"

Performing a Test

If you want a simple test to find out if it works, try the following which writes a log trace to two text files on the root of C Drive:

cscript.exe //NoLogo AddLocalGpStartupScript.vbs startup cmd.exe "/c echo %date% %time% startup>> c:\startup.log"

cscript.exe //NoLogo AddLocalGpStartupScript.vbs shutdown cmd.exe "/c echo %date% %time% shutdown>> c:\shutdown.log"

Why isn’t there a Logon and Logoff Script Version?

There is actually one and it doesn’t work. The process of installing the Logon Script isn’t quite a simple as the process for a Startup Script because it has to be written into the registry on each user account. Consequently, until such a time that I have the will to automate this part, while it performs the installation legally, it doesn’t execute unless you go in and press the apply button on the Logon Script UI.

PDF of MSKB 824184 How to set up Automated System Recovery on a Windows Server 2003 computer that is running Remote Installation Services

System Requirements:

  • Windows Server 2003

The Problem:

For some reason Microsoft removed KB824184 from the website, yet it is the only reference to the fact that you can merge Automated System Recovery (ASR) with Remote Installation Service (RIS) to perform floppy-less network recovery installs under Windows Server 2003.

It is also reported that they even still test exam candidates on knowing that it is possible despite the fact that it isn’t mentioned where else!

This article provides a PDF download of 824184 in the interest of aiding the curious.

The Fix

Download a PDF of the (clearly not intended for real use by anyone) instructions here.

Download: 824184 How to set up Automated System Recovery on a Windows Server 2003 computer that is running Remote Installation Services (71 KB)

Error 0x80070005 when using SWbemLocator.ConnectServer to initiate a WMI session despite using the correct username and password

System Requirements:

  • WMI 1.5 or higher
  • Windows 95, 98, 98SE, Millennium
  • Windows NT 4.0, 2000, XP, 2003, Vista, 2008, 7

The Problem:

When using WMI’s SWbemLocator.ConnectServer class to log onto a remote system, you receive an 0x80070005 access denied error (Decimal -2147024891).

This error occurs even though the username and password are correct and the account credentials are synchronised properly between the local and remote machine – either by domain or manually in a workgroup.

More Info

The classfull connection line for using SWbemLocator is:

Set objWMIService = objSWbemLocator.ConnectServer(<computerName>, <wmiDefaultClassPath>, <username>, <password>)

for example:

Set objWMIService = objSWbemLocator.ConnectServer("192.168.0.100", "root\cimv2", "Administrator", "12345abcde")

The Fix

There is a very good chance that the problem you are having is to do with the username you are entering. You need to ensure that you are prefixing the username with the logon domain.

For example if your domain is camie.local your username should be camie\Administrator

Set objWMIService = objSWbemLocator.ConnectServer("192.168.0.100", "root\cimv2", "camie\Administrator", "12345abcde")

But I’m using a workgroup!

Don’t worry, you can do one of three things.

  1. Prefix the remote machine name (the local logon domain)
  2. Prefix the workgroup
  3. Send a null logon domain
Set objWMIService = objSWbemLocator.ConnectServer("192.168.0.100", "root\cimv2", "myHostName\Administrator", "12345abcde")

Set objWMIService = objSWbemLocator.ConnectServer("192.168.0.100", "root\cimv2", "workgroup\Administrator", "12345abcde")

Set objWMIService = objSWbemLocator.ConnectServer("192.168.0.100", "root\cimv2", "\Administrator", "12345abcde")

Using one of the above, you should be able to connect to the remote workstation. If you are dealing with a mix of workgroups or cannot know the hostname in advance I suggest using \<username> with I have tested to work on Windows 95 right through to Windows 7.

Microsoft JET Database Engine error ‘80040e21’ – Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done.

System Requirements:

  • Windows NT 4.0
  • Windows 2000
  • Windows XP
  • Windows Server 2003
  • Windows Vista
  • Windows Server 2008
  • Windows 7

The Problem:

When you attempt to connect to a Microsoft Access database using the ODBC provider Microsoft.Jet.OLEDB.4.0 you receive the error message:

Microsoft JET Database Engine error ‘80040e21’
Multiple-step OLE DB operation generated errors. Check each OLE DB status value, if available. No work was done./path/file.asp, line ##

 

More Information:

There are a number of issues that can cause this error, they are poorly documented elsewhere online but the information is there; connection string, registry values slightly offset and so fourth. This document deals with one specific issue which is related to the idea of this being caused by an incompatible type value.

The chances of you running into this are quite extreme, however it is an issue in JET (Microsoft Access) that doesn’t exist in Microsoft SQL Server and thus if you are dealing with code transitioning you may want to know about the problem in this very extreme and unlikely situation.

You shouldn’t need to reboot to solve the problem, it didn’t in my case. However, if nothing happens do restart before progressing to the next step.

SQL Example

The following SQL Statement will execute on Microsoft SQL Server and return a RecordSet however the same SQL on JET 4.0 will result in the error message outlined above.

SELECT
Student.StudentID,
Student.FirstName,
Student.LastName,
Student.EMail,
null AS studentPhotoBLOB,
Left(StudentID,1) AS YearPrefix
FROM Student;

No, it isn’t the T-SQL LEFT() statement that is the problem. The issue lies in the “null AS studentPhotoBLOB”.

The idea behind this is that space has been reserved in the record set. Why would you want to do this? If you want to drop the record set directly into an array, then ADO can do this for you using the GetRecords method. However if you want to change the structure you have to re-parse the array and relocate the data into a new structure. You can inset a null named record and use the space in the GetRecords array later for other purposes.

The problem here is that null is not a data type that is supported by JET; it is supported by Microsoft SQL Server however.

The simplest way to remedy the situation is to either change the SQL or dynamically detect JET to change the variable type to a commonly supported data type, for example a String.

SELECT
Student.StudentID,
Student.FirstName,
Student.LastName,
Student.EMail,
” AS studentPhotoBLOB,
Left(StudentID,1) AS YearPrefix
FROM Student;

This is naughty, however in a weak typed language such as ASP it isn’t a real problem given the situation outlined above. The use of ” instead of null forces the data type of the column into a string and thus it can be parsed by JET.