I recently had an interesting issue come about with a bunch of old school legacy machines scattered around several offices that contained identical disk images and SMS/SCCM agent GUID’s. The unintended consequences of this situation are computers improperly referenced in a collection plan. In addition machines were improperly re-imaged and applications inadvertently deployed. Our in-house solution was to create a script to parse a CSV (comma delimited) file including all machine names with duplicate GUID’s and run the following tasks:
Sponsors, article continues below...
1) Make sure machine is pingable
2) Stop SMS/SCCM Agent
3) Delete SMSCFG.ini
4) Start SMS/SCCM Agent to generate new SMSCFG.ini including GUID.
5) Report results to c:\FixSMSGUID_Results.csv
NOTE: Be sure you have sufficient rights on the destination machines before running this script!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 | '########################################################################### '## VB Script: FixSMSGUID.vbs ############################################## '## Purpose: Delete SMS.ini and restart SMS service. ####################### '## Author: Stephen Leuthold http://www.blogmynog.com ##################################### '## Created: 2008-04-22 #################################################### '## Last Modified: 2008-09-30 ############################################## '########################################################################### '## Changelog On Error Resume Next Const wbemFlagReturnImmediately = &h10 Const wbemFlagForwardOnly = &h20 Const ForReading = 1 Const strOutputFile = "c:\FixSMSGUID_Results.csv" '**************************************************************************** ' Obtain CSV list of file. '**************************************************************************** 'Set objArgs = WScript.Arguments 'If objArgs.Count > 0 Then ' Set str = WScript.Arguments.Item(1) ' Set intMode = WScript.Arguments.Item(2) 'ElseIf objArgs.Count = 0 Then 'Via browse dialog box if cmd line arguments null MsgBox "Select duplicate GUID CSV" Set objDialog = Createobject("Useraccounts.Commondialog") objDialog.Filter = "Duplicate GUID CSV|*.csv" 'objDialog.Flags = &H0200 objDialog.Filterindex = 1 objDialog.InitialDir = "C:\" 'objDialog.dialogTitle = "Select a file" intResult = objDialog.Showopen If(intResult = 0) Then Wscript.Echo "No duplicate GUID CSV file selected! Exiting.." Wscript.quit Else strHostList = objDialog.FileName End If '**************************************************************************** 'END CSV file. '**************************************************************************** '**************************************************************************** Dim arrDupGUID(1) Dim i, sleepDur, intSleep, strService, objService, errReturn, strMsg intSleep = 10000 sleepDur = 0 intSleepRetry = 1000 strService = "ccmexec" Set objFSO = CreateObject("Scripting.FileSystemObject") Set objTextFile = objFSO.OpenTextFile _ (strHostList, ForReading) Wscript.echo "Removing duplicate GUID's...." Wscript.echo 'Create Fix SMS GUID status CSV If objFSO.FileExists(strOutputFile) Then objFSO.DeleteFile(strOutputFile) End If Set objOutputFile = objFSO.CreateTextFile(strOutputFile, True) 'Loop through each line of file Do Until objTextFile.AtEndOfStream strNextLine = objTextFile.Readline i = 0 For Each strItem In CSVParse(strNextLine) arrDupGUID(i) = strItem i = i + 1 Next strHost = arrDupGUID(0) strStatus = arrDupGUID(1) Wscript.Echo "Hostname: "& strHost 'Wscript.echo "Machines status: "& strStatus 'If machines GUID has not already been fixed. If strStatus = "Done" Then Wscript.echo "Host already done, skipping: "& strHost strMsg = "Done" Wscript.echo Else If fctIsAlive(strHost) = False Then strMsg = "Ping timeout" Wscript.echo strMsg Wscript.echo Else If Len(strHost) = 0 Then Wscript.echo "Hostname string is null, check your IMPORT file!...Exiting..." Wscript.quit End If Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strHost) If Err.Number Then 'Wscript.Echo Err.Number Wscript.Echo "Error: "& Err.Description 'Wscript.Echo "Could not connect to the WMI Service" Wscript.Echo strMsg = Err.Description Else Set objService = objWMIService.Get("Win32_Service.Name='" & strService & "'") 'Get Windows Directory Set objOS = objWMIService.ExecQuery("Select * from Win32_OperatingSystem") For Each colOS In objOS strWindowsDir = colOS.WindowsDirectory Next 'Wscript.Echo "Windows Dir: "& strWindowsDir Set objIniDel = GetObject("winMgmts:CIM_DataFile.Name='" & strWindowsDir & "\SMSCFG.INI'") '########################################################## 'Stop the service, delete SMSCFG.INI and start the service. '########################################################## 'Stop SMS Host Agent Service Wscript.Echo "Stopping SMS Agent Host service" errReturn = objService.StopService() If errReturn > 0 Then 'Wscript.Echo "Error: " & errReturn strMsg = errReturn.Description Wscript.Echo strMsg End If Wscript.Echo "Waiting..." 'Wscript.Echo "State: "& objService.State Wscript.Sleep intSleep strState = objService.State 'Make sure service is stopped before continuing Do Until strState = "Stopped" Wscript.Echo "Service still stopping, waiting..." Wscript.Sleep intSleepRetry Set objState = objWMIService.Get("Win32_Service.Name='" & strService & "'") strState = objState.State sleepDur = sleepDur + 1 If sleepDur = 30 Then strMsg = "Timeout Could not stop SMS Agent service" strState = "Stopped" End If 'Wscript.Echo "State: "& strState Loop 'Delete SMSCFG.ini file Wscript.Echo "Deleting SMSCFG.ini file" errReturn = objIniDel.delete If errReturn > 0 Then 'Wscript.Echo "Error: " & errReturn Wscript.Echo "Could not delete SMSCFG.ini file" strMsg = "Could not delete SMSCFG.ini file" End If 'Start SMS Host Agent Service Wscript.Echo "Starting SMS Agent Host service" errReturn = objService.StartService() If errReturn > 0 Then 'Wscript.Echo "Error: " & errReturn Wscript.Echo "Service could not start" End If 'Reset sleep duration sleepDur = 0 'Make sure service is started before continuing Do Until strState = "Running" Wscript.Echo "Service still starting, waiting..." Wscript.Sleep intSleepRetry Set objState = objWMIService.Get("Win32_Service.Name='" & strService & "'") strState = objState.State 'Wscript.Echo "State: "& strState sleepDur = sleepDur + 1 If sleepDur = 30 Then strMsg = "Timeout Could not Start SMS Agent service" strState = "Running" End If Loop Wscript.echo "SMS Host Service is Running" 'Wscript.echo "Done with: "& strHost If Len(StrMsg) = 0 Then strMsg = "Done" End If Wscript.echo End If 'END If cannot connect End If ' If cannot ping End If 'END If machines GUID has not already been fixed. Err.Clear objOutputFile.Writeline strHost & ","& strMsg StrMsg = "" Loop 'END - Loop through line of file 'END - Reading CSV 'Close file for Writing objOutputFile.Close Wscript.quit Function fctIsAlive(strHostOrIP) 'Function to make sure machine is pingable. 'Stolen from http://www.fpschultze.de/uploads/wmiping.vbs.txt Dim objSh, objCmd, strCmd strCmd = "%ComSpec% /C %SystemRoot%\system32\ping.exe -n 1 " & strHostOrIP & " | " _ & "%SystemRoot%\system32\find.exe /c /i " & Chr(34) & "ttl=" & Chr(34) Set objSh = WScript.CreateObject("WScript.Shell") Set objCmd = objSh.Exec(strCmd) fctIsAlive = CBool(Trim(objCmd.StdOut.ReadAll)) Set objCmd = Nothing Set objSh = Nothing End Function Function CSVParse(ByVal strLine) ' Function to parse comma delimited line and return array ' of field values. ' Stolen from http://www.rlmueller.net/Programs/ReadCSV.txt Dim arrFields Dim blnIgnore Dim intFieldCount Dim intCursor Dim intStart Dim strChar Dim strValue Const QUOTE = """" Const QUOTE2 = """""" ' Check for empty string and return empty array. If (Len(Trim(strLine)) = 0) then CSVParse = Array() Exit Function End If ' Initialize. blnIgnore = False intFieldCount = 0 intStart = 1 arrFields = Array() ' Add "," to delimit the last field. strLine = strLine & "," ' Walk the string. For intCursor = 1 To Len(strLine) ' Get a character. strChar = Mid(strLine, intCursor, 1) Select Case strChar Case QUOTE ' Toggle the ignore flag. blnIgnore = Not blnIgnore Case "," If Not blnIgnore Then ' Add element to the array. ReDim Preserve arrFields(intFieldCount) ' Makes sure the "field" has a non-zero length. If (intCursor - intStart > 0) Then ' Extract the field value. strValue = Mid(strLine, intStart, _ intCursor - intStart) ' If it's a quoted string, use Mid to ' remove outer quotes and replace inner ' doubled quotes with single. If (Left(strValue, 1) = QUOTE) Then arrFields(intFieldCount) = _ Replace(Mid(strValue, 2, _ Len(strValue) - 2), QUOTE2, QUOTE) Else arrFields(intFieldCount) = strValue End If Else ' An empty field is an empty array element. arrFields(intFieldCount) = Empty End If ' increment for next field. intFieldCount = intFieldCount + 1 intStart = intCursor + 1 End If End Select Next ' Return the array. CSVParse = arrFields End Function |
‘————- END COPY ——————’
Please note that an alternative solution might be found within a Microsoft Technet SMSANDMOM blog entry I recently happened upon.
MY NORMAL DISCLAIMER APPLIES: Although I have used this script with success in my environment, every environment varies. You run this script at your own risk blogmynog.com and associates are in no way responsible for damages incurred running any provided scripts on blogmynog.com or associated websites. Be sure to test this in a non-production environment first before using it in production.
Get a syntax error on line 12 char 35
Try copying it again, for some reason the text editor replaced "&" with "&".
Thank you!
If there's anyone on this still can you please tell me where to get a script or SQL query to find duplicated guids on SMS 2.0, I know is old but is what we have in place and it looks like we have tons of duplicates
Please let me know and thank you in advance
hi, if anyone still there, can you please help me. when I am running the script, it just gave me a message box saying " select a file" but there is no brows button nothing just a "OK" button. what should I have to do when it shows select the file or is there any changes happened in the original script?.
Regards,