widsnet.com
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
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment

No trackbacks yet.