Bob Hoss Posted August 31, 2006 Share Posted August 31, 2006 First time poster - so be nice please I generally don't think about posting my code, but I think this one could be helpful. I developed a script to push a patch via WMI over 8 domains (same forest) utilizing alternate credentials when needed. Anyway - I hope someone gets some use out of this. I did have us entering credentials instead of reading from a file (they are now stored in a text file username@domain.com,password) but if it bombed you had to type them all back in again. Also, I hard coded the servers list file name - but that could easily be changed. The servers should be in a plain text file, one per line. The script does the following: Tries To Ping the Server - If no ping - log If ping good - Tries to Connect to WMI on the remote server using current credentials. If that doesn't work - it goes through a list of potential credentials per machine. If No WMI connect - log If WMI connects - Then check to make sure it's not already patched - if so - log it If not patched - kick off remote process for patch from UNC on server where share is WIDE open. The Patch Installs - and forces a reboot of the machine Once the machine reboots - we log install successful expandcollapse popup#include <file.au3> #include <Array.au3> #include <Date.au3> ;Create Vars ;Var For Counting Through The PassWord Array $i = 0 ;Var For Reboot $strNoReboot = "" ;Var For Counting Servers $strServerCount = 1 ;Title Text For Status Screens $strTitleText = "Installing Patch On " ;Read Servers List Into An Array Dim $arrServers[1] _FileReadToArray(@ScriptDir &"\wmi.txt", $arrServers) $strServersTotal = $arrServers[0] _ArrayDelete($arrServers,0) ;Create Log File With a Time Date Stamp Where End User Chose Folder At $strLogFileName = "MS06-040-" &@MON &"-" &@MDAY &"-" &@YEAR &"-" &@HOUR &@MIN &@SEC &".csv" $strLogFilePath = @ScriptDir &"\" &$strLogFileName $filLogFile = FileOpen($strLogFilePath, 1) FileWriteLine($filLogFile, "Server_Name,Status") ;Get A List Of Credentials To Try Dim $arrCredentials[1][2] $x = 0 $filPassWords = FileOpen(@ScriptDir &"\passwords.txt",0) While 1 $line = FileReadLine($filPassWords) If @error = -1 Then ExitLoop If $x >=1 Then ReDim $arrCredentials[$x+1][2] EndIf $arrTemp = StringSplit($line, ",") $arrCredentials[$x][0] = $arrTemp[1] $arrCredentials[$x][1] = $arrTemp[2] $x = $x + 1 Wend ;Create The WbemScripting.SWbemLocator Object $objSWbemLocator = ObjCreate("WbemScripting.SWbemLocator") ;Error Handling For Com Object $objError = ObjEvent("AutoIt.Error","WMI_Connect_Error") ;Go Through Each Server In List Try To Install MS06-040 Patch For $strComputer in $arrServers SplashTextOn($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal, @CR &"Pinging Server...", 400, 125, 700 ,600, 18) ;Ping Server $strPing = Ping($strComputer,250) ;Ping Good - Try To Connect To WMI If $strPing Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Trying To Connect To WMI With Current Credentials...") ;Try Logged On Credentials First $objWMIService = $objSWbemLocator.ConnectServer($strComputer, "root\cimv2") ;Loop Through Credentials List And See If We Can Connect To Server With Alt. Credentials Do ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Trying To Connect To WMI With Alternate Credentials...") If $i = Ubound($arrCredentials)-1 Then ExitLoop Global $strUserName = $arrCredentials[$i][0] Global $strPassWord = $arrCredentials[$i][1] $i = $i + 1 If $strUserName = "administrator" Then Global $objWMIService = $objSWbemLocator.ConnectServer($strComputer, "root\cimv2", $strcomputer &"\" &$strUserName, $strPassword) Else Global $objWMIService = $objSWbemLocator.ConnectServer($strComputer, "root\cimv2", $strUserName, $strPassword) EndIf Until IsObj($objWMIService) ;Ping Bad - Log It Else ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Couldn't Ping Server - Writing To Log") FileWriteLine($filLogFile, $strComputer &",Couldn't Ping,Couldn't Ping,Couldn't Ping") ContinueLoop EndIf ;Connected to WMI O.K. If IsObj($objWMIService) Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"WMI Connected O.K." &@CR &"Querying Server For OS Details...") ;Get OS Details $colWIN32OS = $objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem") For $objItem in $colWIN32OS $strOS = $objItem.Caption $strSP = $objItem.ServicePackMajorVersion Next ;Change Caption Name As Needed Select ;Windows 2000 Case StringInStr($strOS, "2000") $strOS = "Windows 2000" $strPatchPath = "\\<ServerName>\<Share>\Windows2000-KB921883-MS06-040.EXE /quiet /log:c:\ms06040.txt /forcerestart /forceappsclose" ;Windows XP Case StringInStr($strOS, "XP") $strOS = "Windows XP" $strPatchPath = "\\<ServerName>\<Share>\WindowsXP-KB921883-x86-ENU.exe /quiet /log:c:\ms06040.txt /forcerestart /forceappsclose" ;Windows 2003 Case StringInStr($strOS, "2003") $strOS = "Windows 2003" $strPatchPath = "\\<ServerName>\<Share>\Windows2003-KB921883-MS06-040.exe /quiet /log:c:\ms06040.txt /forcerestart /forceappsclose" EndSelect ;How To Handle Win2K With Wrong SP If $strOS = "Windows 2000" AND $strSP <> "4" Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"WMI Connected O.K." &@CR &"Server Is At Wrong Service Pack - Writing To Log.") FileWriteLine($filLogFile,$strComputer &",Windows 2000 Server - Incorrect Service Pack Level - Did Not Patch") ContinueLoop EndIf ;Find Out If Patch Already Installed ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"WMI Connected O.K." &@CR &"OS Version is " &$strOS &@CR &"Checking To See If Patch Is Already Installed...") $colWin32Hotfix = $objWMIService.ExecQuery("SELECT * FROM Win32_QuickFixEngineering Where ServicePackInEffect = 'KB921883'") For $objItem In $colWin32Hotfix If $objItem.ServicePackInEffect Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"WMI Connected O.K." &@CR &"OS Version is " &$strOS &@CR &"Patch Is Already Installed - Writing To Log.") FileWriteLine($filLogFile,$strComputer &",Already Patched") ContinueLoop(2) EndIf Next ;Install Patch ;Set Impersonation Level 3 $objWMIService.Security_.ImpersonationLevel = 3 ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Connected To WMI" &@CR &"OS Version is " &$strOS &@CR &"Installing Patch...") ;Connect to WMI and Start Patch From UNC $objProcess = $objWMIService.Get("Win32_Process") ; msgbox(0,"t","Would be installing now.") $objProcess.Create($strPatchPath) ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Connected To WMI" &@CR &"OS Version is " &$strOS &@CR &"Patch Installation Initiated at " &_NowTime()) $begin = TimerInit() Do $StrRebootPing = Ping($strComputer) Sleep(3000) $dif = TimerDiff($begin) If $dif >= 300000 Then $strWait = msgbox(1,"Question....","You've waited over 5 minutes for " &$strComputer &" to reboot - would you like to wait another 5?") ;Exit Loop And Go To Next Server If $strWait = 2 Then $strNoReboot = "Did Not Reboot." ExitLoop EndIf ;Wait Again If $strWait = 1 Then $begin = TimerInit() ContinueLoop EndIf EndIf Until $StrRebootPing = 0 ;Server Never Rebooted - User Skipped Waiting To Move To Next Server In List If $strNoReboot = "Did Not Reboot." Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Connected To WMI" &@CR &"OS Version is " &$strOS &@CR &"Patch May Not Have Installed - Server Did Not Reboot. Writing To Log.") FileWriteLine($filLogFile,$strComputer &",Did Not Reboot - Needs Checked.") ContinueLoop EndIf ;Rebooted and All is Well If $strNoReboot = "" Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Connected To WMI" &@CR &"OS Version is " &$strOS &@CR &"Patch Installed - Server Rebooted. Writing To Log.") FileWriteLine($filLogFile,$strComputer &",Installation Sucessful.") EndIf EndIf ;Could Not Connect To WMI If NOT IsObj($objWMIService) Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Couldn't Connect To WMI - Writing To Log") FileWriteLine($filLogFile,$strComputer &",Couldn't Connect To WMI,Couldn't Connect To WMI,Couldn't Connect To WMI") EndIf ;Reset Vars For Next Machine In List $i = 0 $strNoReboot = "" ;Add To Count $strServerCount = $strServerCount + 1 Next ;Turn Off SplashScreen SplashOff() ;Close Log File FileClose($filLogFile) ;Quit Script Exit ;Error Handling Function For WbemScripting.SWbemLocator Object - Forces Return To Code Instead Of Bombing Out Func WMI_Connect_Error() Return("Caught Error") EndFunc Link to comment Share on other sites More sharing options...
blitzkrg Posted August 31, 2006 Share Posted August 31, 2006 (edited) First time poster - so be nice please ;Ping Good - Try To Connect To WMI If $strPing Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Trying To Connect To WMI With Current Credentials...") shouldnt $strPing be compaired to something? Edited August 31, 2006 by blitzkrg Link to comment Share on other sites More sharing options...
Bob Hoss Posted August 31, 2006 Author Share Posted August 31, 2006 I believe it compares as true and then there's an else statement to comply with the no ping. Please correct if wrong - thanks for the note! ;Ping Good - Try To Connect To WMI If $strPing Then ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Trying To Connect To WMI With Current Credentials...") shouldnt $strPing be compaired to something? Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted September 1, 2006 Moderators Share Posted September 1, 2006 I believe it compares as true and then there's an else statement to comply with the no ping. Please correct if wrong - thanks for the note!You are correct. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
blitzkrg Posted September 1, 2006 Share Posted September 1, 2006 You are correct.i learn something new everyday Link to comment Share on other sites More sharing options...
Bob Hoss Posted September 5, 2006 Author Share Posted September 5, 2006 Found a Bug - posting the fix... If NOT IsObj($objWMIService) Then Do ControlSetText($strTitleText &$strComputer &" " &$strServerCount &"\" &$strServersTotal,"","Static1", "Ping Status - O.K." &@CR &"Trying To Connect To WMI With Alternate Credentials...") If $i = Ubound($arrCredentials)-1 Then ExitLoop Global $strUserName = $arrCredentials[$i][0] Global $strPassWord = $arrCredentials[$i][1] $i = $i + 1 If $strUserName = "administrator" or $strUserName = "administrato" Then Global $objWMIService = $objSWbemLocator.ConnectServer($strComputer, "root\cimv2", $strcomputer &"\" &$strUserName, $strPassword) Else Global $objWMIService = $objSWbemLocator.ConnectServer($strComputer, "root\cimv2", $strUserName, $strPassword) EndIf Until IsObj($objWMIService) EndIf Link to comment Share on other sites More sharing options...
Bob Hoss Posted September 8, 2006 Author Share Posted September 8, 2006 Another fix.... If $i = Ubound($arrCredentials) Then ExitLoop Instead of If $i = Ubound($arrCredentials)-1 Then ExitLoop Link to comment Share on other sites More sharing options...
myk3 Posted January 5, 2011 Share Posted January 5, 2011 I am trying to do something similar but only on one domain.. I have never used WMI before i read this post.. I was playing around with autoit / wmi and have been able to retrieve system info but have yet to try to install a patch remotely.. Is there any advice to get started ?? Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted January 5, 2011 Moderators Share Posted January 5, 2011 myk3, I seriously doubt you will get a reply from a thread that has been dead for over 4 years! Just search the forum (the facility is at top right of the page) for WMI - there are lots of scripts out there. If you do not find anything that answers your specific question then start your own topic in the General Help forum. M23 Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now