widsnet.com
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