Friday, March 30, 2007

VBScript: Execute process remotely with WMI

For our terminal/citrix servers we have to regularly run delprof command for deleting inactive user profiles to minimize disk space consumption. The annoying part is to login into each of the servers just to run this command. Even though delprof supports deleting profiles on remote servers with the switch /C:\\<computername>, but that runs terribly slow over WAN links.

A workaround is to remotely execute delprof (or for that matter any other command) on the remote server by using tools like PsExec which installs a temporary service on the remote machine to be able to execute process remotely, and unintalls the same service after the process finishes. Because of its dependency on installing a service, PsExec might not always be a viable option in production environment. So, what's an alternative now?

Enter WMI.

It offers the capability to execute process remotely with the limitation of not allowing any user interaction - the process will run in the background without showing any interface on user's session, which is a perfect feature for running silent installs or non-interactive processes, for example, delprof /q/i

Below is the code snippet which does the job.

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2:Win32_Process")
intReturn = objWMIService.Create(
"delprof /q/i", Null, Null, intProcessID)

This script also uses Popup function of WScript.Shell instance to display message box which disappears after specified seconds - great for showing quick status messages without waiting for any user interaction.

Here is the complete script which executes delprof command on the target server and shows before and after free space information at the end, on the client side.

Assumptions:

  • Delprof executable should already be installed on the target server.
  • Because the script also checks before and after free space on C: drive, it assumes that \Documents and Settings folder is located on server's C: drive.

Reference: http://www.microsoft.com/technet/scriptcenter/resources/qanda/dec06/hey1208.mspx

NOTE: For some weird reason, delprof command is case sensitive. Therefore, DELPROF /q/i does not recognize the "quiet" and "ignore" switches and still prompts: Delete inactive profiles on \\SERVERNAME? (Yes/No)

Wednesday, March 21, 2007

VBScript: Unload Non-Active User Hives From Registry

In Windows 2000 Terminal Server/Citrix environments, it often happens that after users have logged off, their user registry hive doesn't unload automatically from HKEY_USERS\, which in turn keeps consuming registry space and causes it to go out of sufficient free space. The workaround is to launch REGEDT32.EXE (on W2K) or REGEDIT (on W2K3) and manually unload user hives from HKU, but again you'll need to manually figure out who all are active users and exclude those from unloading. This manual process requires converting each of the logged-in user IDs into their respective SIDs and searching them in HKU to exclude.

This script addresses these issues and automates the process of unloading only non-active user hives from HKEY_USERS. This script first converts each of the loaded user SIDs into user names, then attempts to unload all but the active ones by matching those user names with the output from 'query user' command. Below are more details:

Expected Input: Target computer name. By default it’ll show local computer name where it is executed from, which can be changed to any target system. This script can be run from the local desktop session, no need to login into remote system.

Definite Output: The output file will open automatically in notepad after script execution, and will be stored in C:\TEMP\UnloadHive-SERVERNAME.log on the system where it is run. The output file shows a quick summary of how many hives unloaded successfully and registry space gained. This script also keeps updating a single log file (CSV) with summary result of each execution - in case any data analysis or trend analysis is required to do in future.

Dependency: Requires psgetsid.exe to be present in the same directory where script is. It is recommended to copy psgetsid.exe in the executable path on the local machine (e.g., C:\Windows\).

Download the script here.