widsnet.com
20Oct/170

Run client actions with vbs

' Set the required variables.
sSoftwareMetering = "Software Metering Usage Report Cycle"
sMachinePolicy = "Request & Evaluate Machine Policy"
sUpdatesSource = "Updates Source Scan Cycle"
sUserPolicy = "Request & Evaluate User Policy"
sHardwareInventory = "Hardware Inventory Collection Cycle"
sSoftwareInventory = "Software Inventory Collection Cycle"
sApplicationEvaluation = "Application Global Evaluation Task"
sSoftwareUpdates = "Software Updates Assignments Evaluation Cycle"
sDiscoveryData = "Discovery Data Collection Cycle"
sMSISourceUpdate = "MSI Product Source Update Cycle"
sFileCollection = "Standard File Collection Cycle"

' Create the CPAppletMgr instance.
Set controlPanelAppletManager = CreateObject("CPApplet.CPAppletMgr")

' Get the available ClientActions object.
Set clientActions = controlPanelAppletManager.GetClientActions()

' Loop through the available client actions. Run the matching client action when it is found.
For Each clientAction In clientActions
    If clientAction.Name = sUpdatesSource Then
        clientAction.PerformAction
    ElseIf clientAction.Name = sSoftwareUpdates Then
    	clientAction.PerformAction
    End If
Next
20Apr/170

Create regvalues from TS variables

script to add in a TS to save certain task sequence variables to the registry, for whatever reason ...
Syntas looks like this. First argument is the start name of the variables. Second argument is the registry key to store the variables:
cscript CreateRegvaluesFromTSVariables.vbs "PostTS" "Software\HM\PostTSInstall"

Const HKEY_LOCAL_MACHINE = &H80000002

Set oRegistry = GetObject("winmgmts:\\.\root\default:StdRegProv")
Set oArguments = WScript.Arguments

If oArguments.Count <> 2 Then
	WScript.Echo "Usage:"
	WScript.Echo "cscript " & Wscript.ScriptName & " ""variableName"" ""RegKey"""
	WScript.Echo " variableName" & vbTab & "Ex: ""HM"" if TS variables are Called HMIPNetmask and HMIPServer"
	WScript.Echo " RegKey" & vbTab & "Ex: Software\HM\ (Always under HKLM)"
	WScript.Echo ""
	WScript.Echo "The name after variableName will be created in the registry under RegKey with the value specified for the variable."
	WScript.Echo "Ex: If Task Sequence Variable HMIPNetmask is set to 255.255.255.0"
	WScript.Echo """IPNetMask"" will be created as a string under RegKey with Value ""255.255.255.0"""
	WScript.Quit 10022 'An invalid argument was supplied.
End If

sVariable = oArguments.Item(0)
sRegKey = oArguments.Item(1)

CreateKey(sRegKey)

'Gather OSD Variables and create registry values
Set osdVar = CreateObject("Microsoft.SMS.TSEnvironment")  
For Each sVar in osdVar.GetVariables() 
	If LCase(Left(sVar, Len(sVariable))) = LCase(sVariable) Then
		sValueName = Replace(sVar, sVariable, "", 1, 1, vbTextCompare)
		sValue = osdVar(sVar)
		If sValue <> "" Then
			CreateStringValue sRegKey, sValueName, sValue
		End if
	End If
Next

Sub CreateKey(sRegKey)
	oRegistry.CreateKey HKEY_LOCAL_MACHINE, sRegKey
End Sub

Sub CreateStringValue(sRegKey, sValueName, sValue)
	oRegistry.SetStringValue HKEY_LOCAL_MACHINE, sRegKey, sValueName, sValue
End Sub
20Apr/170

Syncronize time in a task sequence

Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("Wscript.Shell")
Set objOSDEnv = CreateObject("Microsoft.SMS.TSEnvironment")
sLogPath = objOSDEnv("_SMSTSLogPath")

sLogFileName = Replace(WScript.ScriptName, ".vbs", ".log")
logThis "LogFile: " & sLogPath & "\" & sLogFileName

sUser = objOSDEnv("_SMSTSReserved1-000")
sPassword = objOSDEnv("_SMSTSReserved2-000")

logThis "%comspec% /c NET USE \\SERVER\IPC$ """ & "<password>" & """ /USER:" & sUser
Set oExec = oShell.Exec("%comspec% /c ""NET USE \\SERVER\IPC$ " & sPassword & " /USER:" & sUser & """")
logThis oExec.StdOut.ReadAll
logThis oExec.StdErr.ReadAll

logThis "%comspec% /c NET TIME \\SERVER /SET /Y"
Set oExec = oShell.Exec("%comspec% /c NET TIME \\SERVER /SET /Y")
logThis oExec.StdOut.ReadAll
If oExec.StdErr.ReadAll <> "" Then
	logThis oExec.StdErr.ReadAll
	wscript.quit(3912)
End If


Sub logThis(strText)
	'Create (if it doesn't exist) and open the logFile for appending
	Set oLogFile = objFSO.OpenTextFile(sLogPath & "\" & sLogFileName, ForAppending, True, 0)
	oLogFile.WriteLine(strText)
	oLogFile.Close	
End Sub
23Sep/150

Remove duplicates in SCCM 2012 based on Name

Simple script that should be scheduled to run on the primary server as the System account. Will fetch all dupliacte objects from ConfigMgr and sort them basen on ResourceID. It will always keep the latest object and delete the ones with older/lower ResourceID.

' This script removes all duplicates in SCCM (based on name)
' Always keeps the object with highest ResourceID (newest)

'Global constants
Const ForReading = 1, ForWriting = 2, ForAppending = 8

strComputer = "SERVER"
strNameSpace = "root\sms\site_SITECODE"

Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oShell = CreateObject("Shell.Application")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\" & strNameSpace)

logThis "Start of script. Query WMI for duplicate computer objects"
' Get all duplicate objects from SCCM. Sort on computername and newest to oldest (highest ResourceID first)
Set colSettings = objWMIService.ExecQuery("SELECT DISTINCT r.* FROM SMS_R_System AS r FULL JOIN SMS_R_System AS s1 ON s1.ResourceId=r.ResourceId FULL JOIN SMS_R_System AS s2 ON s2.Name=s1.Name WHERE s1.Name=s2.Name AND s1.ResourceId!=s2.ResourceId ORDER BY r.Name, r.ResourceID DESC")
sName = ""
logThis "Found " & colSettings.Count & " objects"
For Each objResource in colSettings
	If sName = objResource.Name Then
		' Delete the old object!
		logThis "Deleting Name: " & objResource.Name & "; ResourceID: " & objResource.ResourceID & "; Client: " & objResource.Client & "; Active: " & objResource.Active & "; MAC: " & Join(objResource.Macaddresses, ",")
		iReturn = DeleteComputer(objWMIService, objResource.ResourceID)
		logThis "Return Code: " & iReturn
		WScript.Sleep 30000
		If sMAC = "" And UBound(objResource.Macaddresses) = 0 Then
			logThis "Save the MAC from this object to the newer object"
			iResourceID = UpdateMAC(objWMIService, objResource.Name, objResource.Macaddresses(0))
			logThis "MAC: " & objResource.Macaddresses(0) & " saved to ResourceID: " & iResourceID
		End If
	Else
		' Keep this one (highest ResourceID) and delete the ones to follow!
		sName = objResource.Name
		sMAC = Join(objResource.Macaddresses, ",")
		logThis "Keeping Name: " & objResource.Name & "; ResourceID: " & objResource.ResourceID & "; Client: " & objResource.Client & "; Active: " & objResource.Active & "; MAC: " & sMAC
   	End If
Next
logThis "End of script"

Function DeleteComputer(objWMIService, sResourceID)
	' Deletes a computer from SCCM
	On Error Resume Next
	Set oResource = objWMIService.Get("SMS_R_System.ResourceID='" & sResourceID & "'")
	oResource.Delete_
	DeleteComputer = Err.Number
End Function

Function UpdateMAC(objWMIService, netBiosName, macAddress)
	' Obtain an InParameters object specific
	' to the method.
	Set siteClass = objWMIService.Get("SMS_Site")
	Set inParams = siteClass.Methods_("ImportMachineEntry").inParameters.SpawnInstance_()
	
	' Add the input parameters.
	inParams.Properties_.Item("MACAddress") = macAddress
	inParams.Properties_.Item("NetbiosName") = netBiosName
	inParams.Properties_.Item("OverwriteExistingRecord") = True
	inParams.Properties_.Item("SMBIOSGUID") = Null
	
	' Add the computer.
	Set outParams = objWMIService.ExecMethod("SMS_Site", "ImportMachineEntry", inParams)
	UpdateMAC = outParams.ResourceID
End Function

Sub logThis(sText)
	Const CommonAppData = &H23&
	sNow = Year(Now) & "-" & Right("0" & Month(Now), 2) & "-" & Right("0" & Day(Now), 2) & " " & Right("0" & Hour(Now), 2) & ":" & Right("0" & Minute(Now), 2)
	sLogFilePath = oShell.Namespace(CommonAppData).Self.Path & "\Company\" & Replace(WScript.ScriptName, ".vbs", ".log", 1, 1, vbTextCompare)
	If oFSO.FolderExists(oFSO.GetParentFolderName(sLogFilePath)) = False Then
		oFSO.CreateFolder(oFSO.GetParentFolderName(sLogFilePath))
	End If
	Set oLogFile = oFSO.OpenTextFile(sLogFilePath, ForAppending, True)
	oLogFile.WriteLine(sNow & " " & sText)
	oLogFile.Close
End Sub
22Jul/140

Nice to have CM2012 vbscripts

Some of these are only slighlty modified from CM SDK. Others are very modified 🙂
Response.Write is for ASP, replace it with Wscript.Echo to use in a script.

First. Connect to CM.

' Set connection = ConnectToCM
Function ConnectToCM
	' Make the connection to CM. Uses constants for servername, username and password
	' Also kind of from the CM SDK. A bit modified
    On Error Resume Next
    Set swbemLocator = CreateObject("WbemScripting.SWbemLocator")
    swbemLocator.Security_.AuthenticationLevel = 6 'Packet Privacy
    
    ' Connect to the server.
    Set swbemServices= swbemLocator.ConnectServer(sCMServer, "root\sms", sCMUser, sCMPassword)
    If Err.Number<>0 Then
        Response.Write "Couldn't connect: " + Err.Description
        Set ConnectToCM = null
        Exit Function
    End If

    ' Determine where the provider is and connect.
    Set providerLoc = swbemServices.InstancesOf("SMS_ProviderLocation")
	For Each location In providerLoc
		If location.ProviderForLocalSite = True Then
			Set swbemServices = swbemLocator.ConnectServer(location.Machine, "root\sms\site_" + location.SiteCode,sCMUser,sCMPassword)
			If Err.Number<>0 Then
				Response.Write "Couldn't connect:" + Err.Description
				Set ConnectToCM = Null
				Exit Function
			End If
			Set ConnectToCM = swbemServices
			Exit Function
		End If
	Next
    Set ConnectToCM = null ' Failed to connect.
End Function

Start with import a new computer. Returns the ResourceID for the new object.

Function AddNewComputer(connection, netBiosName, smBiosGuid, macAddress)
	' Import a new computer into CM. Based on function from CM SDK
	' Returns the ResourceID for the new object
	If (IsNull(smBiosGuid) = True) And (IsNull(macAddress) = True) Then
		Response.Write "smBiosGuid or macAddress must be defined"
		AddNewComputer = False
		Exit Function
	End If     

	If IsNull(macAddress) = False Then
		macAddress = Replace(macAddress,"-",":")
	End If    

	' Obtain an InParameters object specific
	' to the method.
	Set siteClass = connection.Get("SMS_Site")
	Set inParams = siteClass.Methods_("ImportMachineEntry").inParameters.SpawnInstance_()

	' Add the input parameters.
	inParams.Properties_.Item("MACAddress") =  macAddress
	inParams.Properties_.Item("NetbiosName") =  netBiosName
	inParams.Properties_.Item("OverwriteExistingRecord") =  False
	inParams.Properties_.Item("SMBIOSGUID") =  smBiosGuid

	' Add the computer.
	Set outParams = connection.ExecMethod("SMS_Site","ImportMachineEntry", inParams)
	AddNewComputer = outParams.ResourceID
End Function

Create a dynamic collection. Returns the CollectionID for the collection.

'sCollectionID = CreateDynamicCollection(connection, sCollName, sComment, True, "SELECT * FROM SMS_R_System WHERE Name LIKE '" & sCountry & "%'", sCollComment, sLimitingCollection)
Function CreateDynamicCollection(connection, newCollectionName, newCollectionComment, ownedByThisSite, queryForRule, ruleName, limitToCollectionID)
	' Function from CM SDK, slightly modified
    ' Create the collection.
    Set newCollection = connection.Get("SMS_Collection").SpawnInstance_
    newCollection.Name = newCollectionName
    newCollection.Comment = newCollectionComment
    newCollection.OwnedByThisSite = ownedByThisSite
    newCollection.LimitToCollectionID = limitToCollectionID
    
    ' Save the new collection and save the collection path for later.
    Set collectionPath = newCollection.Put_    
	
    ' Create a new collection rule object for validation.
    Set queryRule = connection.Get("SMS_CollectionRuleQuery")
    
    ' Validate the query (good practice before adding it to the collection). 
    validQuery = queryRule.ValidateQuery(queryForRule)
    
    ' Continue with processing, if the query is valid.
    If validQuery Then
        ' Create the query rule.
        Set newQueryRule = QueryRule.SpawnInstance_
        newQueryRule.QueryExpression = queryForRule
        newQueryRule.RuleName = ruleName
        
        ' Add the new query rule to a variable.
        Set newCollectionRule = newQueryRule
        
        ' Get the collection.
        Set newCollection = connection.Get(collectionPath.RelPath)
        
        ' Add the rules to the collection.
        newCollection.AddMembershipRule newCollectionRule
		
        ' Call RequestRefresh to initiate the collection evaluator.
        newCollection.RequestRefresh True
    End If
	CreateDynamicCollection = newCollection.CollectionID
End Function

Perhaps get the ID of a Folder, based on the name, to put the new collection in.

Function GetCollectionFolderID(connection, sName)
	' Returns FolderID for a folder under "Device Collections" based on Name
	Set oNodeID = connection.ExecQuery("SELECT * FROM SMS_ObjectContainerNode WHERE Name='" & sName & "' AND ObjectType='5000'") '5000 for SMS_Collection_Device
	If oNodeID.Count = 1 Then
		GetCollectionFolderID = oNodeID.ItemIndex(0).ContainerNodeID
	Else
		GetCollectionFolderID = ""
	End If
End Function

Move the collection to the folder.

Sub MoveCollectionToFolder(connection, CollectionID, TargetFolderID)
	ObjectType = 5000 '5000 is SMS_Collection_Device
	SourceFolderID = 0 ' Root folder
	On Error Resume Next
	' Move one collection. 
	sourceItems = Array(CollectionID)
	Set objInstance = connection.Get("SMS_ObjectContainerItem")
	
	' Set up the in parameters 
	Set objInParam = objInstance.Methods_("MoveMembers").inParameters.SpawnInstance_() 
	objInParam.Properties_.Item("InstanceKeys") = sourceItems 
	objInParam.Properties_.Item("ContainerNodeID") = SourceFolderID 
	objInParam.Properties_.Item("TargetContainerNodeID") = TargetFolderID 
	objInParam.Properties_.Item("ObjectType") = ObjectType
	
	' Call the method. 
	Set objOutParams = connection.ExecMethod("SMS_ObjectContainerItem","MoveMembers",objInParam)
End Sub

Create a new variable on the collection.

Sub CreateCollectionVariable(connection, name, value, mask, collectionId, precedence)
	' Sub from CM SDK
	' See if the settings collection already exists. if it does not, create it.
	Set settings = connection.ExecQuery("Select * From SMS_CollectionSettings Where CollectionID = '" & collectionID & "'")
	
	If settings.Count = 0 Then
		'Response.Write "Creating collection settings object"
		Set collectionSettings = connection.Get("SMS_CollectionSettings").SpawnInstance_
		collectionSettings.CollectionID = collectionId
		collectionSettings.Put_
	End If  
	
	' Get the collection settings object.
	Set collectionSettings = connection.Get("SMS_CollectionSettings.CollectionID='" & collectionId &"'" )
	
	' Get the collection variables.
	collectionVariables = collectionSettings.CollectionVariables
	
	' Create and populate a new collection variable.
	Set collectionVariable = connection.Get("SMS_CollectionVariable").SpawnInstance_
	collectionVariable.Name = name
	collectionVariable.Value = value
	collectionVariable.IsMasked = mask
	
	' Add the new collection variable.
	ReDim Preserve collectionVariables (UBound (collectionVariables)+1)
	Set collectionVariables(UBound(collectionVariables)) = collectionVariable
	collectionSettings.CollectionVariables=collectionVariables
	collectionSettings.Put_
End Sub

Get the collectionID based on name.

Function GetCollectionID(sName)
	' Return CollectionID based on Name
	Set oCollection = connection.ExecQuery("SELECT * FROM SMS_Collection WHERE Name='" & sName & "'")
	If oCollection.Count > 0 Then
		GetCollectionID = oCollection.ItemIndex(0).CollectionID
	Else
		GetCollectionID = ""
	End If
End Function

Add computer to a collection with direct membership.

Function AddComputerToCollection(connection, sResourceID, sCollectionID)
	' Add a computer to a collection with direct membership
	On Error Resume Next
	set collection = connection.Get("SMS_Collection.CollectionID='" & sCollectionID & "'")
	set collectionRule = connection.Get("SMS_CollectionRuleDirect").SpawnInstance_

	collectionRule.ResourceClassName = "SMS_R_System"
	collectionRule.ResourceID = sResourceID
	collection.AddMembershipRule collectionRule
	
	AddComputerToCollection = Err.Number
End Function

Two functions to get the ResourceID or the Computername, based on the other OR MAC.

Function GetResourceID(connection, sComputernameOrMAC)
	' Returns the ResourceID for a computer based on MAC or Name
	Set oResource = connection.ExecQuery("SELECT ResourceID FROM SMS_R_System WHERE Name='" & sComputernameOrMAC & "' OR MACAddresses='" & sComputernameOrMAC & "'")
	If oResource.Count > 0 Then 
		GetResourceID = oResource.ItemIndex(0).ResourceID
	Else
		GetResourceID = False
	End If
End Function

Function GetComputername(connection, sResourceIdOrMAC)
	' Returns the computername for a computer based on MAC or ResourceID
	Set oResource = connection.ExecQuery("SELECT Name FROM SMS_R_System WHERE ResourceID LIKE '" & sResourceIdOrMAC & "' OR MACAddresses='" & sResourceIdOrMAC & "'")
	If oResource.Count > 0 Then 
		GetComputername = oResource.ItemIndex(0).Name
	Else
		GetComputername = False
	End If
End Function

Clear last PXE Advertisement for a computer to be able to PXE boot the ocmputer again.

Function ClearPxeAdvertisementResource(connection, sResourceID)
	On Error Resume Next
	' Set up the Resource array parameter.
	resources = Array(1)
	resources(0) = sResourceID

	Set InParams = connection.Get("SMS_Collection").Methods_("ClearLastNBSAdvForMachines").InParameters.SpawnInstance_
	InParams.ResourceIDs = resources
	connection.ExecMethod "SMS_Collection", "ClearLastNBSAdvForMachines", InParams
	
	ClearPxeAdvertisementResource = Err.number
End Function

Is the computer already a member of a collection?

Function IsMemberOfCollection(connection, sCollID, sResourceID)
	' Check if ResourceID is member of CollectionID
	Set oExist = connection.ExecQuery("SELECT * FROM SMS_FullCollectionMembership WHERE CollectionID='" & sCollID & "' AND ResourceID='" & sResourceID & "'")
	If oExist.Count = 1 Then
		IsMemberOfCollection = True
	Else
		IsMemberOfCollection = False
	End If
End Function

Check for valid IP/Subnet/netmask and MAC syntax.

Function isValidIP(sIP)
	' not really ... just checking that the value is between 1.0.0.0 and 255.255.255.255
	' That way this function works for IP, Subnet and Netmask instead of having 3 different functions
	Set regEx = New RegExp
	regEx.Pattern = "^([1-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])([.]([0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5])){3}$"
	regEx.IgnoreCase = True
	isValidIP = regEx.Test(sIP)
End Function

Function isValidMAC(sMAC)
	' Syntax: XX:XX:XX:XX:XX:XX
	Set regEx = New RegExp
	regEx.Pattern = "^([0-9A-F]{2}[:]){5}([0-9A-F]{2})$"
	regEx.IgnoreCase = True
	isValidMAC = regEx.Test(sMAC)
End Function

And last, delete the computer object.

Function DeleteComputer(connection, sResourceID)
	' Deletes a computer from SCCM
	On Error Resume Next
	Set oResource = connection.Get("SMS_R_System.ResourceID='" & sResourceID  & "'")
	oResource.Delete_
	DeleteComputer = Err.Number
End Function
6Oct/110

remote WMI test script

Follow up to http://widsnet.com/2011/10/stop-install-on-uncertified-hardware/
A simple script to test if the user "queryWMIUser" has the required rights to ask WMI questions remote to the site servers.

strTS must be a TS with Driver Packages referenced in it. (Apply Driver Package)
strDriverPackage must be a driver package referenced in the TS.

On Error Resume Next 
strUser = "domain\queryWMIUser"
strPassword = "Password"
strTS = "SMS00001"
strDriverPackage = "SMS00004"

Set objLocator = CreateObject("WbemScripting.SWbemLocator")

For Each strSiteServer In Array("server1", "server2", "server3", "server4", "server5")
	Set objWMIService = objLocator.ConnectServer(strSiteServer, "root\sms", strUser, strPassword)
	Set colItems = objWMIService.ExecQuery("SELECT * FROM SMS_ProviderLocation")
	strErr = "Read Sitecode, Err: " & Err.Number & " " & Err.Description
	For Each objItem in colItems
		strSitecode = objItem.SiteCode
	Next
	WScript.Echo "Server: " & strSiteServer & " " & strSitecode
	WScript.Echo strErr
	Err.Clear
			
	Set objWMIService = objLocator.ConnectServer(strSiteServer, "root\sms\site_" & strSitecode, strUser, strPassword)
	Set colItems = objWMIService.ExecQuery("SELECT * FROM SMS_TaskSequenceReferencesInfo WHERE PackageID='" & strTS & "' AND ReferencePackageID='" & strDriverPackage & "'")
	WScript.Echo "Read TSRefPackage, Err: " & Err.Number & " " & Err.Description
	If colItems.Count = 1 And Err.Number = 0 Then
		WScript.Echo strUser & " has access to read TSRefPackages"
	Else
		WScript.Echo strUser & " has no access to read TSRefPackages"
	End If
	Err.Clear
	
	strSitecode = ""
	WScript.Echo ""
Next
6Oct/110

ZTITatoo remake

The Tattoo script that comes with MDT is not working as one would expect when running a x64 OS.
ConfigMgr client put the values to tattoo the registry with under "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Deployment 4\" in the registry. Nothing wrong with that when ConfigMgr read the values since the COnfigMgr client is 32 bit x86.
But if you want to use the same values/variables for instance with a WMI filter when applying a GPO, it wont work. The WMI filter in the GPO will try to read the values under "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Deployment 4\"

WMI filter example to get the GPO to only apply to computer that was installed with a specific version of OSImage:

SELECT * FROM Microsoft_BDD_Info WHERE OSDImagePackageID='SMS00001'

This script will correct the ZTITatoo script and put the values/variables in both places in the registry. And also add a few more variables set on some collections. this is of cource editable.

job id="ZTITatoo">
	<script language="VBScript" src="ZTIUtility.vbs"/>
	<script language="VBScript">

' // ***************************************************************************
' // 
' // Copyright (c) Microsoft Corporation.  All rights reserved.
' // 
' // Microsoft Deployment Toolkit Solution Accelerator
' //
' // File:      ZTITatoo.wsf
' // 
' // Version:   5.0.1641.0
' // 
' // Own Version: 2.1.0.0
' // 20101025 konjnw: Added logging for vars: KeyboardLocale, SystemLocale, UserLocale
' //                  TimeZoneName
' // 20101027 konjnw: Complete rewrite of script to support X64 OS
' //                  Added logging for vars: Language, PCRole, FormFactor
' // 20101028 konjnw: Added logging for vars: OSDImagePackageId, OSDImageVersion, CDAVersion
' // 
' // Purpose:   Tattoo the machine with identification and version info
' // 
' // Usage:     cscript.exe [//nologo] ZTITatoo.wsf [/debug:true]
' // 
' // ***************************************************************************

Option Explicit
RunNewInstance


'//----------------------------------------------------------------------------
'//  Global Constants
'//----------------------------------------------------------------------------

Const HKLM = &H80000002


'//----------------------------------------------------------------------------
'//  Main Class
'//----------------------------------------------------------------------------

Class ZTITatoo

	'//----------------------------------------------------------------------------
	'//  Class instance variable declarations
	'//----------------------------------------------------------------------------

	' No variables are required
	

	'//----------------------------------------------------------------------------
	'//  Constructor to initialize needed global objects
	'//----------------------------------------------------------------------------

	Private Sub Class_Initialize

		' No initialization is required

	End Sub
	
	
	'//----------------------------------------------------------------------------
	'//  Main routine
	'//----------------------------------------------------------------------------

	Function Main

		Dim iRetVal
		Dim sValue
		Dim oDate
		Dim sMOFFile
		Dim sCmd
		Dim sWbem
		Dim sArch
		Dim objCtx
		Dim objLocator 
		Dim objServices 
		Dim objStdRegProv

		iRetVal = Success

		' Make sure we're really in the full OS

		If oEnvironment.Item("OSVersion") = "WinPE" then
			oLogging.ReportFailure "ERROR - ZTITatoo task should be running in the full OS, aborting.", 9601
		End if

		' Check if running in 64 bit OS

		If oEnvironment.Item("Architecture") = "X64" Then
			sArch = "X64"
		Else
			sArch = "X86"
		End If
		
		Do Until sArch = "Done"
			Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
			If sArch = "X64" Then
				objCtx.Add "__ProviderArchitecture", 64
				objCtx.Add "__RequiredArchitecture", True
			Else
				objCtx.Add "__ProviderArchitecture", 32
				objCtx.Add "__RequiredArchitecture", True
			End If
			Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
			Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx)
			Set objStdRegProv = objServices.Get("StdRegProv") 
	
	
			'//----------------------------------------------------------------------------
			'//  Copy and compile the MOF
			'//----------------------------------------------------------------------------
	
			iRetVal = oUtility.FindFile("ZTITatoo.mof", sMOFFile)
			If iRetVal <> Success then
	
				oLogging.CreateEntry "Unable to find ZTITatoo.mof, information will not be available via WMI.", LogTypeInfo
	
			Else
				
				sWbem = oEnv("WINDIR") & "\System32\Wbem"
				
				oLogging.CreateEntry "Copying " & sMOFFile & " to " & sWbem & "\ZTITatoo.mof.", LogTypeInfo
				If oFSO.FileExists(sWbem & "\ZTITatoo.mof") then
					oFSO.GetFile(sWbem & "\ZTITatoo.mof").Attributes = 0
				End if
				oFSO.CopyFile sMOFFile, sWbem & "\ZTITatoo.mof", true
	
				sCmd = sWbem & "\MOFCOMP.EXE -autorecover " & oEnv("WINDIR") & "\System32\Wbem\ZTITatoo.mof"
				oLogging.CreateEntry "About to compile MOF: " & sCmd, LogTypeInfo
				iRetVal = oShell.Run(sCmd, 0, true)
				oLogging.CreateEntry "MOFCOMP return code = " & iRetVal, LogTypeInfo
	
			End if
	
	
			'//----------------------------------------------------------------------------
			'//  Record the deployment details
			'//----------------------------------------------------------------------------
	
			iRetVal = objStdRegProv.CreateKey(HKLM, "Software\Microsoft\Deployment 4")
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Deployment Method", oEnvironment.Item("DeploymentMethod"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Deployment Type", oEnvironment.Item("DeploymentType"))
	
			Set oDate = CreateObject("WbemScripting.SWbemDateTime")
			oDate.SetVarDate(Now())
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Deployment Timestamp", oDate.Value)
	
	
			'//----------------------------------------------------------------------------
			'//  If this is Lite Touch, populate the task sequence details
			'//----------------------------------------------------------------------------
	
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Task Sequence ID", oEnvironment.Item("TaskSequenceID"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Task Sequence Name", oEnvironment.Item("TaskSequenceName"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Task Sequence Version", oEnvironment.Item("TaskSequenceVersion"))
			
	
			'//----------------------------------------------------------------------------
			'//  If this is ConfigMgr, populate the package ID and program name
			'//----------------------------------------------------------------------------
	
			sValue = oEnvironment.Item("_SMSTSSiteCode") & ":" & oEnvironment.Item("_SMSTSPackageID")
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Windows NT\CurrentVersion", "CM_DSLID", sValue)
	
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "OSD Package ID", oEnvironment.Item("_SMSTSPackageID"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "OSD Program Name", "*")
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "OSD Advertisement ID", oEnvironment.Item("_SMSTSAdvertID"))
	
	
			'//----------------------------------------------------------------------------
			'//  Own Changes Begin
			'//----------------------------------------------------------------------------
	
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "KeyboardLocale", oEnvironment.Item("KeyboardLocale"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "SystemLocale", oEnvironment.Item("SystemLocale"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "UserLocale", oEnvironment.Item("UserLocale"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "TimeZoneName", oEnvironment.Item("TimeZoneName"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "Language", oEnvironment.Item("Language"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "PCRole", oEnvironment.Item("PCRole"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "FormFactor", oEnvironment.Item("FormFactor"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "CDAVersion", oEnvironment.Item("CDAVersion"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "OSDImagePackageID", oEnvironment.Item("OSDImagePackageID"))
			iRetVal = objStdRegProv.SetStringValue(HKLM, "Software\Microsoft\Deployment 4", "OSDImageVersion", oEnvironment.Item("OSDImageVersion"))
	
	
			'//----------------------------------------------------------------------------
			'//  Own Changes End
			'//----------------------------------------------------------------------------
			If sArch = "X64" Then
				sArch = "X86"
			Else
				sArch = "Done"
			End If
		Loop

		Main = iRetVal

	End Function

End Class

	</script>
</job></pre>
And the mof file.
<pre class="brush:xml">
//==================================================================
// Register Registry property provider (shipped with WMI)
// Refer to WMI SDK documentation for use
//==================================================================

#pragma namespace("\\\\.\\root\\cimv2")

// Registry instance provider
instance of __Win32Provider as $InstProv
{
	Name    ="RegProv" ;
	ClsID   = "{fe9af5c0-d3b6-11ce-a5b6-00aa00680c3f}" ;
	ImpersonationLevel = 1;
	PerUserInitialization = "False";
};

instance of __InstanceProviderRegistration
{
	Provider    = $InstProv;
	SupportsPut = True;
	SupportsGet = True;
	SupportsDelete = False;
	SupportsEnumeration = True;
};


// Registry property provider
instance of __Win32Provider as $PropProv
{
	Name    ="RegPropProv" ;
	ClsID   = "{72967901-68EC-11d0-B729-00AA0062CBB7}";
	ImpersonationLevel = 1;
	PerUserInitialization = "False";
};

instance of __PropertyProviderRegistration
{
	Provider     = $PropProv;
	SupportsPut  = True;
	SupportsGet  = True;
};


//==================================================================
// BDD Information class and instance definition
//==================================================================

#pragma namespace ("\\\\.\\root\\cimv2")

// Class definition

#pragma deleteclass("Microsoft_BDD_Info",nofail)
[DYNPROPS]
class Microsoft_BDD_Info 
{
	[key]
	string InstanceKey;

	string DeploymentMethod;
	string DeploymentType;
	datetime DeploymentTimestamp;

	string BuildID;
	string BuildName;
	string BuildVersion;

	string OSDPackageID;
	string OSDProgramName;
	string OSDAdvertisementID;

	string TaskSequenceID;
	string TaskSequenceName;
	string TaskSequenceVersion;

	string KeyboardLocale;
	string SystemLocale;
	string UserLocale;
	string TimeZoneName;
	string Language;
	string PCRole;
	string FormFactor;
	string OSDImagePackageId;
	string OSDImageVersion;
	string CDAVersion;
};


// Instance definition

[DYNPROPS]
instance of Microsoft_BDD_Info
{
	InstanceKey = "@";

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Deployment Method"), Dynamic, Provider("RegPropProv")]
	DeploymentMethod;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Deployment Type"), Dynamic, Provider("RegPropProv")]
	DeploymentType;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Deployment Timestamp"), Dynamic, Provider("RegPropProv")]
	DeploymentTimestamp;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Build ID"), Dynamic, Provider("RegPropProv")]
	BuildID;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Build Name"), Dynamic, Provider("RegPropProv")]
	BuildName;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Build Version"), Dynamic, Provider("RegPropProv")]
	BuildVersion;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|OSD Package ID"), Dynamic, Provider("RegPropProv")]
	OSDPackageID;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|OSD Program Name"), Dynamic, Provider("RegPropProv")]
	OSDProgramName;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|OSD Advertisement ID"), Dynamic, Provider("RegPropProv")]
	OSDAdvertisementID;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Task Sequence ID"), Dynamic, Provider("RegPropProv")]
	TaskSequenceID;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Task Sequence Name"), Dynamic, Provider("RegPropProv")]
	TaskSequenceName;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Task Sequence Version"), Dynamic, Provider("RegPropProv")]
	TaskSequenceVersion;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|KeyboardLocale"), Dynamic, Provider("RegPropProv")]
	KeyboardLocale;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|SystemLocale"), Dynamic, Provider("RegPropProv")]
	SystemLocale;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|UserLocale"), Dynamic, Provider("RegPropProv")]
	UserLocale;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|TimeZoneName"), Dynamic, Provider("RegPropProv")]
	TimeZoneName;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|Language"), Dynamic, Provider("RegPropProv")]
	Language;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|PCRole"), Dynamic, Provider("RegPropProv")]
	PCRole;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|FormFactor"), Dynamic, Provider("RegPropProv")]
	FormFactor;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|OSDImagePackageId"), Dynamic, Provider("RegPropProv")]
	OSDImagePackageId;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|OSDImageVersion"), Dynamic, Provider("RegPropProv")]
	OSDImageVersion;

	[PropertyContext("local|HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Deployment 4|CDAVersion"), Dynamic, Provider("RegPropProv")]
	CDAVersion;

};
6Oct/110

Log all task sequence variables

Does exactly what the title says

' // ***************************************************************************
' // 
' // Logging all variables used in current Task Sequence.
' //
' // File:      ZTILogVariables.vbs
' // 
' // Version:   1.0.0.0
' // 
' // Purpose:   Find all variables and their values.
' // 
' // Usage:     cscript.exe ZTILogVariables.vbs
' // 
' // ***************************************************************************

Const ForAppending = 8

Set oTSenv = CreateObject("Microsoft.SMS.TSEnvironment") 
Set oFSO = CreateObject("scripting.filesystemobject")
Set oLogFile = oFSO.OpenTextFile(oTSenv("_SMSTSLogPath") & "\" & Replace(WScript.ScriptName, "vbs", "log"), ForAppending, True)

oLogFile.WriteLine("=== Logging all variables ===")

For Each oVar In oTSEnv.GetVariables
	oLogFile.WriteLine(oVar & ": " & oTSEnv(oVar))
Next

oLogFile.Close
6Oct/110

Locale do not match LocaleName

When installing Windows 7 with MDT 2010 and ConfigMgr 2007 there is a bug when changing the Locale for the user.
The Locale variables used in MDT 2010 when running "%scriptroot%\zticonfigure.wsf" are KeyboardLocale, SystemLocale, UILocale and UserLocale.

Assume the build image are using UserLocale=en-US but during deployment we change this to UserLocale=sv-SE. The unattend.xml will be updated with the new value and when any user first log on to the computer it looks like it is set to sv-SE.

One way to spot the problem is to run Print-> Page Setup in MSPaint. The Margins will be set to "inches" instead of "millimeters".
And the problem can be seen in the registry under "HKCU\Control Panel\International\LocaleName" which in this scenario will be set to "sv-SE" but "HKCU\Control Panel\International\Locale" will be "00000409" (1033) which is en-US.

the work around is to open "Region and Language" and under "Formats:" change to anything and press "Apply" and then change back to what you are using and press "OK".

The more automated work around is to run this script in the OS Deployment Task Sequence.

I've had a case regarding this with Microsoft but they wont fix the problem since a manual work around exist. I'am trying to get them to release this as a KB so that others with the same problem can find this work around. This automated work around that is. Not the manual one.

Command Line to run in the OSD TS somewhere after "Setup Windows and ConfigMgr":
cscript "%ScriptRoot%\ZTILocaleFix.vbs"

' // ***************************************************************************
' // 
' // Fixing default user profile when using a different locale than en-US.
' //
' // File:      ZTILocaleFix.vbs
' // 
' // Version:   1.1.0.0
' // 
' // Changes:   1.0.0.0 First version
' //            1.1.0.0 Changed chart used for LocaleName and Locale values
' //
' // Purpose:   Make Locale work with LocaleName.
' // 
' // Usage:     cscript.exe ZTILocaleFix.vbs
' // 
' // ***************************************************************************

Set objShell = WScript.CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
strDefaultUserHive = "C:\Users\Default\NTUSER.DAT"
strTempReg = "HKEY_USERS\DefaultHive"

LogThis "Checking for file: " & strDefaultUserHive
If Not objFSO.FileExists(strDefaultUserHive) Then
	LogThis "File not found!"
	WScript.Quit 2
End If

LogThis "Loading Default User Hive into " & strTempReg
objShell.Run("Reg.exe load " & strTempReg & " " & strDefaultUserHive), 0, True
LogThis "Reading Locale and LocaleName from Default User Hive"
strLocaleName = objShell.RegRead(strTempReg & "\Control Panel\International\LocaleName")
strLocale = objShell.RegRead(strTempReg & "\Control Panel\International\Locale")
LogThis "LocaleName: " & strLocaleName
LogThis "Locale: " & strLocale

LogThis "Finding correct Locale based on LocaleName"
' Previous chart http://msdn.microsoft.com/en-us/library/0h88fahh(v=vs.85).aspx
' New chart from http://msdn.microsoft.com/en-us/library/cc233968(v=PROT.10).aspx
Select Case strLocaleName
	Case "ar": strCorrectLocale = "0001"
	Case "bg": strCorrectLocale = "0002"
	Case "ca": strCorrectLocale = "0003"
	Case "zh-Hans": strCorrectLocale = "0004"
	Case "zh-Hant": strCorrectLocale = "7c04"
	Case "cs": strCorrectLocale = "0005"
	Case "da": strCorrectLocale = "0006"
	Case "de": strCorrectLocale = "0007"
	Case "el": strCorrectLocale = "0008"
	Case "en": strCorrectLocale = "0009"
	Case "es": strCorrectLocale = "000a"
	Case "fi": strCorrectLocale = "000b"
	Case "fr": strCorrectLocale = "000c"
	Case "he": strCorrectLocale = "000d"
	Case "hu": strCorrectLocale = "000e"
	Case "is": strCorrectLocale = "000f"
	Case "it": strCorrectLocale = "0010"
	Case "ja": strCorrectLocale = "0011"
	Case "ko": strCorrectLocale = "0012"
	Case "nl": strCorrectLocale = "0013"
	Case "no": strCorrectLocale = "0014"
	Case "pl": strCorrectLocale = "0015"
	Case "pt": strCorrectLocale = "0016"
	Case "rm": strCorrectLocale = "0017"
	Case "ro": strCorrectLocale = "0018"
	Case "ru": strCorrectLocale = "0019"
	Case "hr": strCorrectLocale = "001a"
	Case "sk": strCorrectLocale = "001b"
	Case "sq": strCorrectLocale = "001c"
	Case "sv": strCorrectLocale = "001d"
	Case "th": strCorrectLocale = "001e"
	Case "tr": strCorrectLocale = "001f"
	Case "ur": strCorrectLocale = "0020"
	Case "id": strCorrectLocale = "0021"
	Case "uk": strCorrectLocale = "0022"
	Case "be": strCorrectLocale = "0023"
	Case "sl": strCorrectLocale = "0024"
	Case "et": strCorrectLocale = "0025"
	Case "lv": strCorrectLocale = "0026"
	Case "lt": strCorrectLocale = "0027"
	Case "tg": strCorrectLocale = "0028"
	Case "fa": strCorrectLocale = "0029"
	Case "vi": strCorrectLocale = "002a"
	Case "hy": strCorrectLocale = "002b"
	Case "az": strCorrectLocale = "002c"
	Case "eu": strCorrectLocale = "002d"
	Case "hsb": strCorrectLocale = "002e"
	Case "mk": strCorrectLocale = "002f"
	Case "tn": strCorrectLocale = "0032"
	Case "xh": strCorrectLocale = "0034"
	Case "zu": strCorrectLocale = "0035"
	Case "af": strCorrectLocale = "0036"
	Case "ka": strCorrectLocale = "0037"
	Case "fo": strCorrectLocale = "0038"
	Case "hi": strCorrectLocale = "0039"
	Case "mt": strCorrectLocale = "003a"
	Case "se": strCorrectLocale = "003b"
	Case "ga": strCorrectLocale = "003c"
	Case "ms": strCorrectLocale = "003e"
	Case "kk": strCorrectLocale = "003f"
	Case "ky": strCorrectLocale = "0040"
	Case "sw": strCorrectLocale = "0041"
	Case "tk": strCorrectLocale = "0042"
	Case "uz": strCorrectLocale = "0043"
	Case "tt": strCorrectLocale = "0044"
	Case "bn": strCorrectLocale = "0045"
	Case "pa": strCorrectLocale = "0046"
	Case "gu": strCorrectLocale = "0047"
	Case "or": strCorrectLocale = "0048"
	Case "ta": strCorrectLocale = "0049"
	Case "te": strCorrectLocale = "004a"
	Case "kn": strCorrectLocale = "004b"
	Case "ml": strCorrectLocale = "004c"
	Case "as": strCorrectLocale = "004d"
	Case "mr": strCorrectLocale = "004e"
	Case "sa": strCorrectLocale = "004f"
	Case "mn": strCorrectLocale = "0050"
	Case "bo": strCorrectLocale = "0051"
	Case "cy": strCorrectLocale = "0052"
	Case "km": strCorrectLocale = "0053"
	Case "lo": strCorrectLocale = "0054"
	Case "gl": strCorrectLocale = "0056"
	Case "kok": strCorrectLocale = "0057"
	Case "syr": strCorrectLocale = "005a"
	Case "si": strCorrectLocale = "005b"
	Case "iu": strCorrectLocale = "005d"
	Case "am": strCorrectLocale = "005e"
	Case "tzm": strCorrectLocale = "005f"
	Case "ne": strCorrectLocale = "0061"
	Case "fy": strCorrectLocale = "0062"
	Case "ps": strCorrectLocale = "0063"
	Case "fil": strCorrectLocale = "0064"
	Case "dv": strCorrectLocale = "0065"
	Case "ha": strCorrectLocale = "0068"
	Case "yo": strCorrectLocale = "006a"
	Case "quz": strCorrectLocale = "006b"
	Case "nso": strCorrectLocale = "006c"
	Case "ba": strCorrectLocale = "006d"
	Case "lb": strCorrectLocale = "006e"
	Case "kl": strCorrectLocale = "006f"
	Case "ig": strCorrectLocale = "0070"
	Case "ii": strCorrectLocale = "0078"
	Case "arn": strCorrectLocale = "007a"
	Case "moh": strCorrectLocale = "007c"
	Case "br": strCorrectLocale = "007e"
	Case "ug": strCorrectLocale = "0080"
	Case "mi": strCorrectLocale = "0081"
	Case "oc": strCorrectLocale = "0082"
	Case "co": strCorrectLocale = "0083"
	Case "gsw": strCorrectLocale = "0084"
	Case "sah": strCorrectLocale = "0085"
	Case "qut": strCorrectLocale = "0086"
	Case "rw": strCorrectLocale = "0087"
	Case "wo": strCorrectLocale = "0088"
	Case "prs": strCorrectLocale = "008c"
	Case "gd": strCorrectLocale = "0091"
	Case "ar-SA": strCorrectLocale = "0401"
	Case "bg-BG": strCorrectLocale = "0402"
	Case "ca-ES": strCorrectLocale = "0403"
	Case "zh-TW": strCorrectLocale = "0404"
	Case "cs-CZ": strCorrectLocale = "0405"
	Case "da-DK": strCorrectLocale = "0406"
	Case "de-DE": strCorrectLocale = "0407"
	Case "el-GR": strCorrectLocale = "0408"
	Case "en-US": strCorrectLocale = "0409"
	Case "es-ES_tradnl": strCorrectLocale = "040A"
	Case "fi-FI": strCorrectLocale = "040B"
	Case "fr-FR": strCorrectLocale = "040C"
	Case "he-IL": strCorrectLocale = "040D"
	Case "hu-HU": strCorrectLocale = "040E"
	Case "is-IS": strCorrectLocale = "040F"
	Case "it-IT": strCorrectLocale = "0410"
	Case "ja-JP": strCorrectLocale = "0411"
	Case "ko-KR": strCorrectLocale = "0412"
	Case "nl-NL": strCorrectLocale = "0413"
	Case "nb-NO": strCorrectLocale = "0414"
	Case "pl-PL": strCorrectLocale = "0415"
	Case "pt-BR": strCorrectLocale = "0416"
	Case "rm-CH": strCorrectLocale = "0417"
	Case "ro-RO": strCorrectLocale = "0418"
	Case "ru-RU": strCorrectLocale = "0419"
	Case "hr-HR": strCorrectLocale = "041A"
	Case "sk-SK": strCorrectLocale = "041B"
	Case "sq-AL": strCorrectLocale = "041C"
	Case "sv-SE": strCorrectLocale = "041D"
	Case "th-TH": strCorrectLocale = "041E"
	Case "tr-TR": strCorrectLocale = "041F"
	Case "ur-PK": strCorrectLocale = "0420"
	Case "id-ID": strCorrectLocale = "0421"
	Case "uk-UA": strCorrectLocale = "0422"
	Case "be-BY": strCorrectLocale = "0423"
	Case "sl-SI": strCorrectLocale = "0424"
	Case "et-EE": strCorrectLocale = "0425"
	Case "lv-LV": strCorrectLocale = "0426"
	Case "lt-LT": strCorrectLocale = "0427"
	Case "tg-Cyrl-TJ": strCorrectLocale = "0428"
	Case "fa-IR": strCorrectLocale = "0429"
	Case "vi-VN": strCorrectLocale = "042A"
	Case "hy-AM": strCorrectLocale = "042B"
	Case "az-Latn-AZ": strCorrectLocale = "042C"
	Case "eu-ES": strCorrectLocale = "042D"
	Case "wen-DE": strCorrectLocale = "042E"
	Case "mk-MK": strCorrectLocale = "042F"
	Case "st-ZA": strCorrectLocale = "0430"
	Case "ts-ZA": strCorrectLocale = "0431"
	Case "tn-ZA": strCorrectLocale = "0432"
	Case "ven-ZA": strCorrectLocale = "0433"
	Case "xh-ZA": strCorrectLocale = "0434"
	Case "zu-ZA": strCorrectLocale = "0435"
	Case "af-ZA": strCorrectLocale = "0436"
	Case "ka-GE": strCorrectLocale = "0437"
	Case "fo-FO": strCorrectLocale = "0438"
	Case "hi-IN": strCorrectLocale = "0439"
	Case "mt-MT": strCorrectLocale = "043A"
	Case "se-NO": strCorrectLocale = "043B"
	Case "ms-MY": strCorrectLocale = "043E"
	Case "kk-KZ": strCorrectLocale = "043F"
	Case "ky-KG": strCorrectLocale = "0440"
	Case "sw-KE": strCorrectLocale = "0441"
	Case "tk-TM": strCorrectLocale = "0442"
	Case "uz-Latn-UZ": strCorrectLocale = "0443"
	Case "tt-RU": strCorrectLocale = "0444"
	Case "bn-IN": strCorrectLocale = "0445"
	Case "pa-IN": strCorrectLocale = "0446"
	Case "gu-IN": strCorrectLocale = "0447"
	Case "or-IN": strCorrectLocale = "0448"
	Case "ta-IN": strCorrectLocale = "0449"
	Case "te-IN": strCorrectLocale = "044A"
	Case "kn-IN": strCorrectLocale = "044B"
	Case "ml-IN": strCorrectLocale = "044C"
	Case "as-IN": strCorrectLocale = "044D"
	Case "mr-IN": strCorrectLocale = "044E"
	Case "sa-IN": strCorrectLocale = "044F"
	Case "mn-MN": strCorrectLocale = "0450"
	Case "bo-CN": strCorrectLocale = "0451"
	Case "cy-GB": strCorrectLocale = "0452"
	Case "km-KH": strCorrectLocale = "0453"
	Case "lo-LA": strCorrectLocale = "0454"
	Case "my-MM": strCorrectLocale = "0455"
	Case "gl-ES": strCorrectLocale = "0456"
	Case "kok-IN": strCorrectLocale = "0457"
	Case "mni": strCorrectLocale = "0458"
	Case "sd-IN": strCorrectLocale = "0459"
	Case "syr-SY": strCorrectLocale = "045A"
	Case "si-LK": strCorrectLocale = "045B"
	Case "chr-US": strCorrectLocale = "045C"
	Case "iu-Cans-CA": strCorrectLocale = "045D"
	Case "am-ET": strCorrectLocale = "045E"
	Case "tmz": strCorrectLocale = "045F"
	Case "ne-NP": strCorrectLocale = "0461"
	Case "fy-NL": strCorrectLocale = "0462"
	Case "ps-AF": strCorrectLocale = "0463"
	Case "fil-PH": strCorrectLocale = "0464"
	Case "dv-MV": strCorrectLocale = "0465"
	Case "bin-NG": strCorrectLocale = "0466"
	Case "fuv-NG": strCorrectLocale = "0467"
	Case "ha-Latn-NG": strCorrectLocale = "0468"
	Case "ibb-NG": strCorrectLocale = "0469"
	Case "yo-NG": strCorrectLocale = "046A"
	Case "quz-BO": strCorrectLocale = "046B"
	Case "nso-ZA": strCorrectLocale = "046C"
	Case "ba-RU": strCorrectLocale = "046D"
	Case "lb-LU": strCorrectLocale = "046E"
	Case "kl-GL": strCorrectLocale = "046F"
	Case "ig-NG": strCorrectLocale = "0470"
	Case "kr-NG": strCorrectLocale = "0471"
	Case "gaz-ET": strCorrectLocale = "0472"
	Case "ti-ER": strCorrectLocale = "0473"
	Case "gn-PY": strCorrectLocale = "0474"
	Case "haw-US": strCorrectLocale = "0475"
	Case "so-SO": strCorrectLocale = "0477"
	Case "ii-CN": strCorrectLocale = "0478"
	Case "pap-AN": strCorrectLocale = "0479"
	Case "arn-CL": strCorrectLocale = "047A"
	Case "moh-CA": strCorrectLocale = "047C"
	Case "br-FR": strCorrectLocale = "047E"
	Case "ug-CN": strCorrectLocale = "0480"
	Case "mi-NZ": strCorrectLocale = "0481"
	Case "oc-FR": strCorrectLocale = "0482"
	Case "co-FR": strCorrectLocale = "0483"
	Case "gsw-FR": strCorrectLocale = "0484"
	Case "sah-RU": strCorrectLocale = "0485"
	Case "qut-GT": strCorrectLocale = "0486"
	Case "rw-RW": strCorrectLocale = "0487"
	Case "wo-SN": strCorrectLocale = "0488"
	Case "prs-AF": strCorrectLocale = "048C"
	Case "plt-MG": strCorrectLocale = "048D"
	Case "gd-GB": strCorrectLocale = "0491"
	Case "ar-IQ": strCorrectLocale = "0801"
	Case "zh-CN": strCorrectLocale = "0804"
	Case "de-CH": strCorrectLocale = "0807"
	Case "en-GB": strCorrectLocale = "0809"
	Case "es-MX": strCorrectLocale = "080A"
	Case "fr-BE": strCorrectLocale = "080C"
	Case "it-CH": strCorrectLocale = "0810"
	Case "nl-BE": strCorrectLocale = "0813"
	Case "nn-NO": strCorrectLocale = "0814"
	Case "pt-PT": strCorrectLocale = "0816"
	Case "ro-MO": strCorrectLocale = "0818"
	Case "ru-MO": strCorrectLocale = "0819"
	Case "sr-Latn-CS": strCorrectLocale = "081A"
	Case "sv-FI": strCorrectLocale = "081D"
	Case "ur-IN": strCorrectLocale = "0820"
	Case "az-Cyrl-AZ": strCorrectLocale = "082C"
	Case "dsb-DE": strCorrectLocale = "082E"
	Case "se-SE": strCorrectLocale = "083B"
	Case "ga-IE": strCorrectLocale = "083C"
	Case "ms-BN": strCorrectLocale = "083E"
	Case "uz-Cyrl-UZ": strCorrectLocale = "0843"
	Case "bn-BD": strCorrectLocale = "0845"
	Case "pa-PK": strCorrectLocale = "0846"
	Case "mn-Mong-CN": strCorrectLocale = "0850"
	Case "bo-BT": strCorrectLocale = "0851"
	Case "sd-PK": strCorrectLocale = "0859"
	Case "iu-Latn-CA": strCorrectLocale = "085D"
	Case "tzm-Latn-DZ": strCorrectLocale = "085F"
	Case "ne-IN": strCorrectLocale = "0861"
	Case "quz-EC": strCorrectLocale = "086B"
	Case "ti-ET": strCorrectLocale = "0873"
	Case "ar-EG": strCorrectLocale = "0C01"
	Case "zh-HK": strCorrectLocale = "0C04"
	Case "de-AT": strCorrectLocale = "0C07"
	Case "en-AU": strCorrectLocale = "0C09"
	Case "es-ES": strCorrectLocale = "0C0A"
	Case "fr-CA": strCorrectLocale = "0C0C"
	Case "sr-Cyrl-CS": strCorrectLocale = "0C1A"
	Case "se-FI": strCorrectLocale = "0C3B"
	Case "tmz-MA": strCorrectLocale = "0C5F"
	Case "quz-PE": strCorrectLocale = "0C6B"
	Case "ar-LY": strCorrectLocale = "1001"
	Case "zh-SG": strCorrectLocale = "1004"
	Case "de-LU": strCorrectLocale = "1007"
	Case "en-CA": strCorrectLocale = "1009"
	Case "es-GT": strCorrectLocale = "100A"
	Case "fr-CH": strCorrectLocale = "100C"
	Case "hr-BA": strCorrectLocale = "101A"
	Case "smj-NO": strCorrectLocale = "103B"
	Case "ar-DZ": strCorrectLocale = "1401"
	Case "zh-MO": strCorrectLocale = "1404"
	Case "de-LI": strCorrectLocale = "1407"
	Case "en-NZ": strCorrectLocale = "1409"
	Case "es-CR": strCorrectLocale = "140A"
	Case "fr-LU": strCorrectLocale = "140C"
	Case "bs-Latn-BA": strCorrectLocale = "141A"
	Case "smj-SE": strCorrectLocale = "143B"
	Case "ar-MA": strCorrectLocale = "1801"
	Case "en-IE": strCorrectLocale = "1809"
	Case "es-PA": strCorrectLocale = "180A"
	Case "fr-MC": strCorrectLocale = "180C"
	Case "sr-Latn-BA": strCorrectLocale = "181A"
	Case "sma-NO": strCorrectLocale = "183B"
	Case "ar-TN": strCorrectLocale = "1C01"
	Case "en-ZA": strCorrectLocale = "1C09"
	Case "es-DO": strCorrectLocale = "1C0A"
	Case "fr-West Indies": strCorrectLocale = "1C0C"
	Case "sr-Cyrl-BA": strCorrectLocale = "1C1A"
	Case "sma-SE": strCorrectLocale = "1C3B"
	Case "ar-OM": strCorrectLocale = "2001"
	Case "en-JM": strCorrectLocale = "2009"
	Case "es-VE": strCorrectLocale = "200A"
	Case "fr-RE": strCorrectLocale = "200C"
	Case "bs-Cyrl-BA": strCorrectLocale = "201A"
	Case "sms-FI": strCorrectLocale = "203B"
	Case "ar-YE": strCorrectLocale = "2401"
	Case "en-CB": strCorrectLocale = "2409"
	Case "es-CO": strCorrectLocale = "240A"
	Case "fr-CG": strCorrectLocale = "240C"
	Case "sr-Latn-RS": strCorrectLocale = "241a"
	Case "smn-FI": strCorrectLocale = "243B"
	Case "ar-SY": strCorrectLocale = "2801"
	Case "en-BZ": strCorrectLocale = "2809"
	Case "es-PE": strCorrectLocale = "280A"
	Case "fr-SN": strCorrectLocale = "280C"
	Case "sr-Cyrl-RS": strCorrectLocale = "281a"
	Case "ar-JO": strCorrectLocale = "2C01"
	Case "en-TT": strCorrectLocale = "2C09"
	Case "es-AR": strCorrectLocale = "2C0A"
	Case "fr-CM": strCorrectLocale = "2C0C"
	Case "sr-Latn-ME": strCorrectLocale = "2c1a"
	Case "ar-LB": strCorrectLocale = "3001"
	Case "en-ZW": strCorrectLocale = "3009"
	Case "es-EC": strCorrectLocale = "300A"
	Case "fr-CI": strCorrectLocale = "300C"
	Case "sr-Cyrl-ME": strCorrectLocale = "301a"
	Case "ar-KW": strCorrectLocale = "3401"
	Case "en-PH": strCorrectLocale = "3409"
	Case "es-CL": strCorrectLocale = "340A"
	Case "fr-ML": strCorrectLocale = "340C"
	Case "ar-AE": strCorrectLocale = "3801"
	Case "en-ID": strCorrectLocale = "3809"
	Case "es-UY": strCorrectLocale = "380A"
	Case "fr-MA": strCorrectLocale = "380C"
	Case "ar-BH": strCorrectLocale = "3C01"
	Case "en-HK": strCorrectLocale = "3C09"
	Case "es-PY": strCorrectLocale = "3c0a"
	Case "fr-HT": strCorrectLocale = "3C0C"
	Case "ar-QA": strCorrectLocale = "4001"
	Case "en-IN": strCorrectLocale = "4009"
	Case "es-BO": strCorrectLocale = "400A"
	Case "en-MY": strCorrectLocale = "4409"
	Case "es-SV": strCorrectLocale = "440A"
	Case "en-SG": strCorrectLocale = "4809"
	Case "es-HN": strCorrectLocale = "480A"
	Case "es-NI": strCorrectLocale = "4C0A"
	Case "es-PR": strCorrectLocale = "500A"
	Case "es-US": strCorrectLocale = "540A"
	Case "bs-Cyrl": strCorrectLocale = "641a"
	Case "bs-Latn": strCorrectLocale = "681a"
	Case "sr-Cyrl": strCorrectLocale = "6c1a"
	Case "sr-Latn": strCorrectLocale = "701a"
	Case "smn": strCorrectLocale = "703b"
	Case "az-Cyrl": strCorrectLocale = "742c"
	Case "sms": strCorrectLocale = "743b"
	Case "zh": strCorrectLocale = "7804"
	Case "nn": strCorrectLocale = "7814"
	Case "bs": strCorrectLocale = "781a"
	Case "az-Latn": strCorrectLocale = "782c"
	Case "sma": strCorrectLocale = "783b"
	Case "uz-Cyrl": strCorrectLocale = "7843"
	Case "mn-Cyrl": strCorrectLocale = "7850"
	Case "iu-Cans": strCorrectLocale = "785d"
	Case "nb": strCorrectLocale = "7c14"
	Case "sr": strCorrectLocale = "7c1a"
	Case "tg-Cyrl": strCorrectLocale = "7c28"
	Case "dsb": strCorrectLocale = "7c2e"
	Case "smj": strCorrectLocale = "7c3b"
	Case "uz-Latn": strCorrectLocale = "7c43"
	Case "mn-Mong": strCorrectLocale = "7c50"
	Case "iu-Latn": strCorrectLocale = "7c5d"
	Case "tzm-Latn": strCorrectLocale = "7c5f"
	Case "ha-Latn": strCorrectLocale = "7c68"
	Case Else
		LogThis "No match for LocaleName!"
		cleanExit
End Select

'Quick convert to correct the number of characters
strCorrectLocale = Right(String(8,"0") & UCase(strCorrectLocale), 8 )

LogThis "CorrectLocale for " & strLocaleName &": " & strCorrectLocale
If strLocale = strCorrectLocale Then
	LogThis "Locales match. Nothing to do"
Else
	LogThis "Locales do not match. Editing hive!"
	objShell.RegWrite strTempReg & "\Control Panel\International\Locale", strCorrectLocale, "REG_SZ"
End If
cleanExit

Sub LogThis(strText)
	WScript.Echo strText
End Sub

Sub cleanExit
	LogThis "Unloading hive and exiting"
	objShell.Run("Reg.exe unload " & strTempReg), 0, True
	WScript.Quit 0
End Sub
6Oct/110

Stop install on uncertified hardware

This is a script to abort the OS deployment during the task sequence if there is no Driver Package referenced in the Task Sequence that matches the Computer Model.

Uses variables "queryWMIUser" and "queryWMIPassword" that must be set on an appropriate collection. Preferably the queryWMIPassword variable is set to "Do not display this value in the ConfigMgr console"

The "queryWMIUser" must of course have the right to query WMI on all sites.

On Error Resume Next
Set oTSenv = CreateObject("Microsoft.SMS.TSEnvironment") 
strSiteServer = oTSenv("_SMSTSMP")
strTaskSequence = oTSenv("_SMSTSPackageID")
strMake = oTSenv("Make")
strModel = oTSenv("Model")
strUser = oTSenv("queryWMIUser")
strPassword = oTSenv("queryWMIPassword")
strTSStep = oTSenv("_SMSTSNextInstructionPointer") -1

If strTaskSequence = "" Then
	WScript.Echo "Unable to get variables from the task sequence, exiting!"
	WScript.Quit 0
End if

WScript.Echo "SiteServer variable: " & strSiteServer
WScript.Echo "TaskSequence variable: " & strTaskSequence
WScript.Echo "Make variable: " & strMake
WScript.Echo "Model variable: " & strModel
WScript.Echo "Query User: " & strUser
WScript.Echo "Query Password: ****"

If oTSenv("isVM") Then
	WScript.Echo "This is a virtual machine"
	WScript.Echo "No hardware check will be performed"
	WScript.Quit 0
End If

Set regEx = New RegExp
regEx.Pattern = "\(.+\)"
regEx.IgnoreCase = True
strModel = regEx.Replace(strModel, "")

regEx.Pattern = "(.*\d+).*$"
strModel = regEx.Replace(strModel, "$1")

WScript.Echo "Cleaned name: " & strModel
WScript.Echo ""

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer(strSiteServer, "root\sms", strUser, strPassword)
Set colItems = objWMIService.ExecQuery("SELECT * FROM SMS_ProviderLocation")
For Each objItem in colItems
	WScript.Echo "Site Code: " & objItem.SiteCode
	strSitecode = objItem.SiteCode
	WScript.Echo "Namespace Path: " & objItem.NamespacePath
Next

strWQL = "SELECT * FROM SMS_TaskSequenceReferencesInfo WHERE PackageID='" & strTaskSequence & "' AND ReferencePackageType=3 and ReferenceName LIKE '%" & strModel & "%'"
WScript.Echo "WQL Search string: " & strWQL
WScript.Echo ""

Set objWMIService = objLocator.ConnectServer(strSiteServer, "root\sms\site_" & strSitecode, strUser, strPassword)
Set colItems = objWMIService.ExecQuery(strWQL)
If colItems.Count > 0 Then
	For Each objItem in colItems
		WScript.Echo "Matching Driver package found"
		WScript.Echo "Driver Package Name: " & objItem.ReferenceName
		WScript.Echo "Driver Package ID: " & objItem.ReferencePackageID
		WScript.Echo "Running on certified hardware"
		WScript.Echo ""
	Next
Else
	strErr = "Hardware not certified!" & vbCrLf & _
		"Computer Model: " & strModel & vbCrLf & _
		"Model does not match any Driver Package Name assigned to this TS" & vbCrLf & _
		"Task Sequence: " & strTaskSequence & vbCrLf & _
		"Failure step: " & strTSStep
	WScript.Echo strErr
	MsgBox strErr, vbOKOnly + vbCritical +vbSystemModal, "Important Information"
	WScript.Quit 1625 ' This installation is forbidden by system policy. Contact your system administrator.
End If