Downgrading Unresponsive Clients via PSexec

Any “client health” team actually does many things other things as well, including client reach, client installation, client movement, and (occasionally) client deinstallation or downgrade. Recently I had to do some client downgrading and movement. You would think that’s easy enough, but as usual (at least in our large environment), there were some tricks. Hopefully the following details will save you some effort when you have to do something similar.

This scenario should be rare – usually you can do many of these operations via simple software distribution. That was my first approach, but for whatever reason it didn’t work (I won’t bore you with the details). So if that fails and you have privileges on the machines, and the number of machines is reasonable, then a more direct approach may be best.

First of all I adapted my main log analysis script to look for online clients that we had privileges on (more details on that in a future post, since it’s a generally useful tool – the core points are to parse a list, do some pinging for online status, and verify privileges). Then the script executes a batch file, which is where things get complex.

You would normally hope to do everything remotely (from your console), but a crucial issue is that not all of the relevant clients will be online at the same time. So you’ll have to run the script multiple times against the same clients (since you don’t necessarily know which were successful the first time). You don’t want to downgrade the clients repeatedly, so you have to check their version to ensure they’re not the lower version (and thus don’t need to be downgraded). How do you check the client version remotely? – via WMI (either in a class or in the registry). But WMI remote access is commonly blocked by the firewall and so that probably won’t work. Thus you have to check client-side. That means two scripts – one to prepare the client and another to do the work, including the version check.

So the first batch file (executed by the script mentioned above), does operations such as:

set computer=%1%

mkdir \\%computer%\c$\temp\ccmsetup_v4
mkdir \\%computer%\c$\temp\ccmsetup_v5
xcopy <source>\smsv4   \\%computer%\c$\temp\ccmsetup_v4 /s /y
xcopy
<source>\smsv5  \\%computer%\c$\temp\ccmsetup_v5 /s /y

copy <source>\RemoveSitecodeRegkeys.reg \\%computer%\c$\temp\ccmsetup_v4
copy <source>\klist_XP2003\klist.exe    \\%computer%\c$\temp\ccmsetup_v4

copy <source>\regcheck.vbs              \\%computer%\c$\temp\ccmsetup_v4
copy <source>\remove_client_part2.bat  
\\%computer%\c$\temp\ccmsetup_v4

<source>\PsExec.exe \\%computer% cmd.exe /c c:\temp\ccmsetup_v4\remove_client_part2.bat

Hopefully you don’t need to use GPO-based site assignments, in which case you won’t need the .reg or klist files (e-mail me if you need those details). And I’m quite sure that klist.exe doesn’t work on XP, which is why I include a shutdown command below (a rare option that happened to be available and relevant in this scenario). An important point is that in my case our remote privileges account does not have ‘log on as a service’ (or similar) privileges. All I can do is copy files to the client and run psexec (and we’re glad to be able to do that). So we’re fairly limited in what we can do.

The second batch file (executed on the client), does operations such as:

cscript.exe //B c:\temp\ccmsetup_v4\regcheck.vbs
IF ERRORLEVEL 1 GOTO DONE

regedit /s c:\temp\ccmsetup_v4\RemoveSitecodeRegkeys.reg
c:\temp\ccmsetup_v4\klist.exe purge
c:\temp\ccmsetup_v5\ccmsetup.exe /uninstall
c:\temp\ccmsetup_v4\ccmsetup.exe SMSSITECODE=<sitecode> FSP=<FSP FQDN>CCMLOGMAXSIZE=100000 CCMENABLELOGGING=TRUE CCMLOGLEVEL=0 DISABLESITEOPT=TRUE DISABLECACHEOPT=TRUE CCMLOGMAXHISTORY=5 SMSCACHESIZE=10000
rem one more time, just in case (but it only helps temporarily on XP):
regedit /s c:\temp\ccmsetup_v4\RemoveSitecodeRegkeys.reg
rem we have to wait for the install to complete:
rem rmdir /s /q c:\temp\ccmsetup_v4
rmdir /s /q c:\temp\ccmsetup_v5
shutdown /r /t 0 /f

:DONE

And to do that client version checking, you’ll need a simple VBscript (regcheck.vbs) such as:

Set oShell = CreateObject("WScript.Shell")
version = oShell.RegRead( "HKLM\SOFTWARE\Microsoft\SMS\Mobile Client\ProductVersion")
wscript.echo version
if version = "4.00.6487.2000" then
  result=2
else
  result=0
end if
wscript.echo "exiting with " & result
wscript.quit(result)

(The ERRORLEVEL behavior was a little non-intuitive to me but testing proved that this worked and I didn’t have time to argue with it.)

Over time we got all the clients downgraded and moved back to where they should and all was good again. But the effort was not quite as trivial as we originally hoped.

Published Thursday, January 06, 2011 9:14 PM by pthomsen

Comments

No Comments