<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6043156720447404006</id><updated>2011-11-28T10:45:56.968+10:00</updated><category term='Printing'/><category term='Scripting'/><category term='NTFS'/><category term='RIS2000'/><category term='PowerShell'/><category term='Performance'/><category term='DNS'/><category term='WMI'/><category term='SQL'/><category term='Drivers'/><category term='VMware'/><category term='Operations Manager 2007'/><category term='Exchange'/><category term='Active Directory'/><category term='Debugging'/><category term='Command-line'/><category term='Server'/><category term='SMS2003'/><category term='Security'/><category term='FSRM'/><category term='Cluster'/><category term='x64'/><category term='Automation'/><category term='Workstation'/><title type='text'>WWoIT - Wayne's World of IT</title><subtitle type='html'>Information regarding Windows Infrastructure, centred mostly around commandline automation and other useful bits of information.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://waynes-world-it.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default?start-index=101&amp;max-results=100'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>137</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7579458184262444078</id><published>2010-08-15T21:11:00.000+10:00</published><updated>2010-08-15T21:11:58.194+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>vSphere Storage vMotion traffic</title><content type='html'>This post provides information on storage vMotion in VMware vSphere 4 with ESXi 4.0 U2 hosts. While using storage vMotion to move data between unconnected storage, I conducted some simple testing to identify the networks and ports used for vMotion.&lt;br /&gt;&lt;br /&gt;I’ve never seen an explanation of how storage vMotion works, and while it seems kind of obvious in retrospect, I thought some people might find this interesting.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Summary&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The scope of a storage vMotion operation is datacenter wide, not limited to clusters or which host can see which storage.&lt;/li&gt;&lt;li&gt;In the testing conducted, storage vMotion relies upon the management network to transfer the disk data between the two ESXi hosts&lt;/li&gt;&lt;li&gt;If this method was used to import a large number of VMs from foreign storage then the limitation would typically be the 1GB vmnic used for the management network.&lt;/li&gt;&lt;li&gt;To allow the migration between datastores not visible by a single host, the VM would also be migrated between hosts.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Scenario&lt;br /&gt;&lt;br /&gt;Two hosts managed by single vCenter instance, vc01:&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;esx01 part of the CLUS1 cluster&lt;/li&gt;&lt;li&gt;esx02 not in a cluster&lt;/li&gt;&lt;li&gt;esx01, connected only to the iSCSI SAN 1&lt;/li&gt;&lt;li&gt;esx02, connected only to the iSCSI SAN 2&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Management network on vmk0 using two GbE interfaces on both hosts. Vmk0 on the management network with load balancing based on the virtual port ID.&lt;br /&gt;&lt;br /&gt;Test&lt;br /&gt;&lt;br /&gt;The test conducted was using storage vmotion to move a virtual machine through VirtualCenter on vc01 from a datastore visible only to esx02 to a datastore visible only to esx01. &lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;The source datastore was LUN02 (visible only to esx02) and the destination datastore was LUN01 (visible only to esx01). &lt;/li&gt;&lt;li&gt;vMotion was used to automatically migrate the VM from esx02 to esx01 (as the VM had moved storage)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Traffic and network usage observed&lt;br /&gt;&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;On esx02 unsupported console, vmk0 source 192.168.0.12.60504 (esx02), destination 192.168.0.11.902 (esx01). &lt;/li&gt;&lt;li&gt;Command: /bin/tcpdump-uw -I vmk0 -nn&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;esx02&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;MbRx 190Mb/sec on software iSCSI NIC – Reading the disk information from iSCSI SAN 2 for the VM&lt;/li&gt;&lt;li&gt;MbTx 136Mb/sec – Transmit the information across the management network to esx01.&lt;/li&gt;&lt;li&gt;Command: resxtop --server esx02 (‘n’ for network information)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;esx01&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;MbRx 120Mb/sec – receiving the disk data from esx02 across the management network&lt;/li&gt;&lt;li&gt;MbTx 200Mb/sec on software iSCSI NIC – writing the data to the SAN across the iSCSI network&lt;/li&gt;&lt;li&gt;Command: resxtop --server esx01 (‘n’ for network information)&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The following diagram shows the traffic flow of storage vMotion on an iSCSI network:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_ErSjACRvSfI/TGfLXN7qPfI/AAAAAAAAFv4/Kxdv6VrSjfg/s1600/Blog137_Storage+vMotion+generic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" ox="true" src="http://1.bp.blogspot.com/_ErSjACRvSfI/TGfLXN7qPfI/AAAAAAAAFv4/Kxdv6VrSjfg/s320/Blog137_Storage+vMotion+generic.jpg" width="303" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7579458184262444078?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7579458184262444078' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7579458184262444078'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7579458184262444078'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2010/08/vsphere-storage-vmotion-traffic.html' title='vSphere Storage vMotion traffic'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ErSjACRvSfI/TGfLXN7qPfI/AAAAAAAAFv4/Kxdv6VrSjfg/s72-c/Blog137_Storage+vMotion+generic.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-1958019842186110224</id><published>2010-08-14T20:17:00.000+10:00</published><updated>2010-08-14T20:17:52.597+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Resizing a VM's Windows system OS with Set-HardDisk</title><content type='html'>With vSphere PowerCLI Update 1 there is now an automated method of increasing the system disk of a virtual machine.  This essentially performs the same thing as I’ve been doing manually for a while now - the disk is resized and mounted to a ‘helper vm’ and diskpart extends the disk, the helper VM is then shutdown and the risk removed, and when the resized VM starts up the OS prompts for a final reboot after detecting the disk change.&lt;br /&gt;&lt;br /&gt;Note that both the target and helper VM must be powered off, and credentials must be passed or the helpervm argument is ignored.  The guest credentials are used on the Windows helper VM to authenticate using the VMtools mechanism to invoke a command inside a VM.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;$guetsusername = "domain\username"&lt;br /&gt;$guestpass = Read-Host "Guest password (administrator of the server)?" -assecurestring&lt;br /&gt;$hostusername = "root"&lt;br /&gt;$hostpass = Read-Host "Host Password (VI SDK access to the ESX host)?" -assecurestring&lt;br /&gt;$hostcredential = new-object System.Management.Automation.PSCredential($hostusername, $hostpass)&lt;br /&gt;$guestcredential = new-object System.Management.Automation.PSCredential($guetsusername, $guestpass)&lt;br /&gt;$sizeGB = 30&lt;br /&gt;$sizeKB = $sizeGB *1024*1024&lt;br /&gt;$harddisk = Get-HardDisk -vm vm01&lt;br /&gt;Set-HardDisk -HardDisk $harddisk[0] -capacityKB $sizeKB -hostcredential $hostcredential -guestcredential $guestcredential -helpervm $vm&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An error occurred when trying to use domain credentials to pass to the vCenter SDK – host credentials are required, not credentials to vCenter (which seems odd).&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;Set-HardDisk -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm helpervm&lt;br /&gt;Set-HardDisk : 4/02/2010 1:25:04 PM    Set-HardDisk    919835D1-AD13-41DF-ABDE-D630E96FE722    While performing operation 'Connect to host service 'https://esx01/sdk' at port 902' the following error occured: 'Insufficient permissions in host operating system'&lt;br /&gt;At line:1 char:13&lt;br /&gt;+ Set-HardDisk  &amp;lt;&amp;lt;&amp;lt;&amp;lt; -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm helpervm&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;Another error occurred when trying to resize a VM, the script used failed.  Note that I tried this manually and it also failed (must have been something particular to that VM).  It was interesting to see that from this it looks like the cmdlet uses the invoke-vmscript to run a remote script through the VMtools interface that calls the diskpart commands.&lt;br /&gt;Set-HardDisk : 4/02/2010 11:22:11 AM    Set-HardDisk    919835D1-AD13-41DF-ABDE-D630E96FE722    Execution of the  script in guest OS on VM 'helpervm' failed: '&lt;br /&gt;Microsoft DiskPart version 5.2.3790.3959&lt;br /&gt;Copyright (C) 1999-2001 Microsoft Corporation.&lt;br /&gt;On computer: HELPERVM&lt;br /&gt;Disk 1 is now the selected disk.&lt;br /&gt;Volume 2 is the selected volume.&lt;br /&gt;The volume you have selected may not be extended.&lt;br /&gt;Please select another volume and try again.&lt;br /&gt;'&lt;br /&gt;At line:1 char:13&lt;br /&gt;+ Set-HardDisk  &amp;lt;&amp;lt;&amp;lt;&amp;lt; -HardDisk $harddisk[0] -capacityKB 31457280 -hostcredential $hostcredential -guestcredential $guestcredential -helpervm $vm&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-1958019842186110224?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=1958019842186110224' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1958019842186110224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1958019842186110224'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2010/08/resizing-vms-windows-system-os-with-set.html' title='Resizing a VM&apos;s Windows system OS with Set-HardDisk'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7435938168542506283</id><published>2010-05-09T17:40:00.001+10:00</published><updated>2010-05-09T17:41:30.753+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Keeping Citrix sessions alive with sendkeys</title><content type='html'>I use the following script as a way of keeping my Citrix session alive to thwart security guys and their over-aggressive timeouts.&lt;br /&gt;&lt;br /&gt;Normally I don't like to use sendkeys, but this seemed like the perfect way to trick ica into thinking keys were being pressed...&lt;br /&gt;&lt;br /&gt;PowerShell and VBScript versions below.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;# Find the wfica.exe process and poke keystrokes at it, preventing a Citrix session from timing out&lt;br /&gt;# Be careful what you have open and what keystrokes you poke&lt;br /&gt;&lt;br /&gt;[System.Object[]]$processes = get-process &amp;#124; where {$_.ProcessName -eq "wfica32.exe"}&lt;br /&gt;if ($processes.count -ge 1) { $process = $processes[0] }&lt;br /&gt;&lt;br /&gt;if ($process -is [System.Diagnostics.Process])&lt;br /&gt;{&lt;br /&gt;  $processes | format-list -property *&lt;br /&gt;&lt;br /&gt;  for (;;)&lt;br /&gt;  {&lt;br /&gt;    [void] [System.Reflection.Assembly]::LoadWithPartialName("'Microsoft.VisualBasic")&lt;br /&gt;&lt;br /&gt;    [Microsoft.VisualBasic.Interaction]::AppActivate($process.Id)&lt;br /&gt;    start-sleep -seconds 1&lt;br /&gt;&lt;br /&gt;    [void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")&lt;br /&gt;    [System.Windows.Forms.SendKeys]::SendWait("1")&lt;br /&gt;    start-sleep -seconds 240&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;Set objWshShell = CreateObject("Wscript.Shell")&lt;br /&gt;&lt;br /&gt;strProcessName = "wfica32.exe"&lt;br /&gt;&lt;br /&gt;intProcessID = 0&lt;br /&gt;Call FindProcessID(strProcessName, intProcessID)&lt;br /&gt;&lt;br /&gt;if (intProcessID &amp;gt; 0) Then&lt;br /&gt; wscript.echo "Found process ID: " &amp; intProcessID&lt;br /&gt;&lt;br /&gt; Do &lt;br /&gt;  objWshShell.AppActivate(intProcessID)&lt;br /&gt;  WScript.Sleep 1000&lt;br /&gt;  objWshShell.SendKeys "1"&lt;br /&gt;  WScript.Sleep 240000&lt;br /&gt; Loop&lt;br /&gt;&lt;br /&gt;End If&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Function FindProcessID(ByRef strProcessName, ByRef intProcessID)&lt;br /&gt;&lt;br /&gt; strQuery = "Select * from Win32_Process Where Name = '" &amp; strProcessName &amp; "'" ' WQL query string looking for the specified process&lt;br /&gt;&lt;br /&gt; Set objNameSpace = GetObject("winmgmts://./root/cimv2")    ' The cimv2 namespace of the local machine&lt;br /&gt;&lt;br /&gt; FindProcessID = vbFalse&lt;br /&gt; Set objProcessSet = objNameSpace.ExecQuery(strQuery)     ' Execute the query&lt;br /&gt; For Each objProcess in objProcessSet      ' For each process in the set, ordered by oldest to newest&lt;br /&gt;  intProcessID = objProcess.ProcessID&lt;br /&gt;  WScript.Echo "Found process, ID: " &amp; intProcessID&lt;br /&gt;  WScript.Echo objProcess.Name &amp; ", " &amp; intProcessID &amp; ", " &amp; objProcess.CreationDate &amp; ", " &amp; objProcess.CommandLine &amp; ", " &amp; objProcess.Priority &amp; ", " &amp; objProcess.WorkingSetSize &amp; ", " &amp; objProcess.PageFileUsage&lt;br /&gt;  FindProcessID = vbTrue&lt;br /&gt; Next&lt;br /&gt;&lt;br /&gt; Set objNameSpace = Nothing : Set objProcessSet = Nothing : Set objProcess = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7435938168542506283?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7435938168542506283' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7435938168542506283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7435938168542506283'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2010/05/keeping-citrix-sessions-alive-with.html' title='Keeping Citrix sessions alive with sendkeys'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-1883751002856445189</id><published>2010-03-27T21:33:00.002+10:00</published><updated>2010-03-27T21:33:53.147+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><title type='text'>More useful command-lines</title><content type='html'>This is the third edition of useful command lines, adding another 95 commands that I've found useful.  Note that many of the command-line calls may require Microsoft utilities (such as dsquery, wmic, dnscmd).&lt;br /&gt;&lt;br /&gt;Most of the commands are for the windows-based command interpreter, with a few PowerShell and ESX service console commands creeping in.  They range from diagnostics, troubleshooting and simply automating recurring tasks.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;br /&gt;See the previous two posts for more command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2009/09/more-useful-command-lines.html"&gt;http://waynes-world-it.blogspot.com/2009/09/more-useful-command-lines.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given an IP and mask, return the subet the IP belongs to&lt;/b&gt;&lt;br /&gt;for /f "tokens=1-8 delims=.- " %i in ('echo 192.168.5.200 255.255.255.0') do set /a Octet1="%i &amp; %m" &amp;gt;nul &amp; set /a Octet2="%j &amp; %n" &amp;gt;nul &amp; set /a Octet3="%k &amp; %o" &amp;gt;nul &amp; set /a Octet4="%l &amp; %p" &amp;gt;nul &amp; Echo %i.%j.%k.%l,!Octet1!.!Octet2!.!Octet3!.!Octet4!,%m.%n.%o.%p&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Disable the internal speaker beep&lt;/b&gt;&lt;br /&gt;sc config beep start= demand &amp; net stop beep&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the Volume Shadow Copy Sets&lt;/b&gt;&lt;br /&gt;vssadmin list shadows&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the volume Shadow Copy storage associations and sizes&lt;/b&gt;&lt;br /&gt;vssadmin list shadowstorage&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create an FSRM storage report to check duplicate files&lt;/b&gt;&lt;br /&gt;Storrept Reports Add /Report:DuplicateFiles /Task:FSRM-DuplicateFiles /Scope:"E:\Data" /Name:"Duplicate Files" /Format:CSV /MailTo:user@somewhere.com&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a scheduled task prior to creating a 2003 FSRM report &lt;/b&gt;&lt;br /&gt;schtasks /create /sc MONTHLY /D 1 /tn FSRM-DuplicateFiles /tr "storrept reports generate /scheduled /task:FSRM-DuplicateFiles" /st 19:00:00 /ru system&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the number of mailboxes on the specified msExchHomeServerName&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(objectClass=User)(objectCategory=Person)(mailnickname=*)(msExchHomeServerName=*servername*))" -limit 0 &amp;#124; find /i /c "cn"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Join text copied from the command-line to a single line when pasting&lt;/b&gt;&lt;br /&gt;Hold down the shift key when copying the text&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the current control set, last known good and failed hives &lt;/b&gt;&lt;br /&gt;reg query HKLM\system\select&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make persistent changes to service control dependencies&lt;/b&gt;&lt;br /&gt;sc \\%server% config snmp depend= EventLog/&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Assign a drive letter to a recently created partition/volume&lt;/b&gt;&lt;br /&gt;diskpart assign letter=e&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Convert a group from type distribution to type security&lt;/b&gt;&lt;br /&gt;dsmod group %groupDN% -secgrp Yes  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for global security or distribution groups&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(groupType:1.2.840.113556.1.4.803:=2))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for global security groups&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(groupType:1.2.840.113556.1.4.803:=-2147483646))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given a list of group DNs, find if those groups are a member of other groups &lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (groups.txt) do @for /f "tokens=*" %m in ('"dsget group -memberof %i &amp;#124; find /i "cn" &amp; if errorlevel 1 Echo Not a member of any groups"') do @echo %i,%m&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the domain controller GUID of the specified DC &lt;/b&gt;&lt;br /&gt;dsquery * "CN=dcname,OU=Domain Controllers,DC=domainRoot" -scope base -attr objectguid&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the domain GUID &lt;/b&gt;&lt;br /&gt;dsquery * "domainRoot" -scope base -attr objectGUID&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Display the local WLBS Microsoft Network Load Balancing configuration&lt;/b&gt;&lt;br /&gt;nlb display&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Perform an LDAP ping against rootDSE to get the DC NETLOGON_SAM_LOGON_RESPONSE&lt;/b&gt;&lt;br /&gt;adfind -rootDSE -f "(&amp;(DnsDomain=domainFQDN)(Host=%computer%)(User=%computer%$)(DomainGuid=\30\FA\03\19\36\4F\47\1D\35\8F\C4\96\72\74\69\B3)(NtVer=\06\00\00\00))"  netLogon&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the master browser for the subnet from NetBIOS browser&lt;/b&gt;&lt;br /&gt;browstat getmaster \Device\NetBT_Tcpip_{3393FDD1-0D42-4DA4-8E53-36D9E00195F5} NETBIOS_DOMAIN_NAME&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the databases on an MSSQL 2005 server&lt;/b&gt;&lt;br /&gt;sqlcmd -S %server% -d master -W -s "," -Q "SELECT NAME FROM sysdatabases Order By Name"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the Service Control Manager security descriptor&lt;/b&gt;&lt;br /&gt;sc sdshow SCMANAGER&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update the Service Control Manager SD on 2003 to allow non-admin access&lt;/b&gt;&lt;br /&gt;sc sdset SCMANAGER D:(A;;CCLCRPRC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update the DACL for a service to allow a user to query and interrogate the svc&lt;/b&gt;&lt;br /&gt;subinacl /service \\%server%\SysmonLog /grant=domain\user=QSI&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find DFS roots from Active Directory&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Dfs-Configuration,CN=System,domainRoot" -filter "(objectClass=fTDfs)"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the DFS trust domain SPC cache&lt;/b&gt;&lt;br /&gt;dfsutil /spcinfo&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the SQL Server version&lt;/b&gt;&lt;br /&gt;sqlcmd -S %server% -d master -W -s "," -Q "SELECT  SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPERTY ('edition')"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the SQL Server 2000 affinity mask &lt;/b&gt;&lt;br /&gt;sqlcmd -S %server% -d master -W -s "," -Q "select c.value from master..sysconfigures c, master..spt_values v, master..syscurconfigs r where v.type = 'C' and v.number = c.config and v.number &amp;gt;= 0 and v.number = r.config and v.name ='affinity mask'"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the SQL Server 2005 affinity mask&lt;/b&gt;&lt;br /&gt;sqlcmd -S %server% -d master -W -s "," -Q "SELECT Name, Value, Minimum, Maximum, Value_in_use, is_dynamic, is_advanced from SYS.Configurations Where Name = 'affinity mask'"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SQL Server 2005 configuration options&lt;/b&gt;&lt;br /&gt;sqlcmd -S %server% -d master -W -s "," -Q "SELECT Name, Value, Minimum, Maximum, Value_in_use, is_dynamic, is_advanced from SYS.Configurations Order By Name"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SQL Server 2000 license information, Mode 0x0 per-seat, 0x2 per-proc&lt;/b&gt;&lt;br /&gt;reg query "\\%server%\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\80\MSSQLLicenseInfo\MSSQL8.00&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SQL Server 2000/2005 instances&lt;/b&gt;&lt;br /&gt;reg query "\\%server%\hklm\software\microsoft\Microsoft SQL Server" /v InstalledInstances&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set environment variables for YYYYMMDD and YYYYMMDDHHMMSS&lt;/b&gt;&lt;br /&gt;for /f "tokens=1-8 delims=/:. " %i in ('echo %date% %time%') do Set DateTime=%l%k%j&amp;Set DateTimeLong=%l%k%j%m%n%o&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Microsoft iSCSI, list sessions&lt;/b&gt;&lt;br /&gt;iscsicli SessionList&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Microsoft iSCSI, Report iSCSI and MPIO version information&lt;/b&gt;&lt;br /&gt;iscsicli VersionInfo&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Show disk usage by username (Windows Resource Kit)&lt;/b&gt;&lt;br /&gt;diskuse c:\&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check whether external or forest trusts have SID filter qurantining enabled&lt;/b&gt;&lt;br /&gt;nltest /domain_trusts /v&lt;br /&gt;&lt;br /&gt;&lt;b&gt;From a list of computers, run a command if the machine responds to a ping&lt;/b&gt;&lt;br /&gt;for /f %i in (computers.txt) do @ping -n 1 %i &amp;gt;nul &amp; if errorlevel 0 if not errorlevel 1 echo %i&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extract performance counters from a perfmon binary file and save as csv &lt;/b&gt;&lt;br /&gt;relog.exe -f csv Perfmon.blg -o perfmon.csv&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make a bootable CD using the specified boot sector file and source files&lt;/b&gt;&lt;br /&gt;oscdimg /m /n /h -bc:\temp\bootsector.bin "c:\temp\source" install.iso&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the Exchange storage groups known to AD&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Configuration,domainRoot" -filter "(&amp;(objectClass=msExchStorageGroup))" -attr name msExchESEParamCircularLog msExchESEParamEventSource msExchESEParamLogFilePath msExchESEParamLogFileSize msExchESEParamSystemPath msExchESEParamZeroDatabaseDuringBackup msExchRecovery msExchESEParamEnableOnlineDefrag msExchESEParamEnableIndexChecking msExchESEParamBaseName msExchESEParamCommitDefault msExchESEParamDbExtensionSize msExchESEParamPageTempDBMin msExchESEParamPageFragment msExchESEParamCheckpointDepthMax&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check if an executable is large address aware (confirms support)&lt;/b&gt;&lt;br /&gt;dumpbin /headers sqlservr.exe&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find all file/registry/thread/event details for a remote machine&lt;/b&gt;&lt;br /&gt;psexec \\%server% -c handle.exe -a &amp;gt; c:\temp\handle.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dump configuration with netsh that can be used to import&lt;/b&gt;&lt;br /&gt;netsh interface ip dump &amp;gt; IPConfig.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reapply settings saved with netsh export&lt;/b&gt;&lt;br /&gt;netsh -f IPConfig.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the SCSI devices for a group of machines&lt;/b&gt;&lt;br /&gt;for /f %i in (computers.txt) do @for /f "tokens=1,2,*" %m in ('"devcon -m:\\%i listclass SCSIAdapter &amp;#124; find /i "VEN""') do @echo %i,%o&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adjust the priority of a process given its PID &lt;/b&gt;&lt;br /&gt;setprio /P %PID% /L 2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the paged and non-paged pool memory allocations&lt;/b&gt;&lt;br /&gt;poolmon&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a local tag file for paged and non-paged pool memory allocations&lt;/b&gt;&lt;br /&gt;poolmon /c&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add a trigger to an existing scheduled task&lt;/b&gt;&lt;br /&gt;jt.exe /sac "\\%server%\c$\windows\Tasks\taskname.job" /ctj StartTime=15:10 StartDate=02/02/2010 type=DAILY typearguments=1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find AdminSDHolder / SDPROP groups in the directory&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(objectClass=Group)(objectCategory=Group)(adminCount=1))"   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for all objects that are protected (that are members of the groups above)&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(adminCount=1)"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Count how many user accounts are protected by the SDPROP process&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(objectClass=User)(objectCategory=Person)(adminCount=1))" &amp;#124; find /i /c "CN="&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find disk and partition relationships&lt;/b&gt;&lt;br /&gt;wmic path Win32_LogicalDiskToPartition&lt;br /&gt;&lt;br /&gt;&lt;b&gt;LDAP string to search for mail-enabled user and contact objects&lt;/b&gt;&lt;br /&gt;"(&amp;(&amp;#124;((objectClass=Contact)(objectClass=User)))(objectCategory=Person)(mailnickname=*))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SCPs (Service Connection Points) for objects other than print queues&lt;/b&gt;&lt;br /&gt;dsquery * -filter "&amp;((objectClass=ConnectionPoint)(!(objectClass=PrintQueue)))"  -limit 0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List VSS Shadowstorage associations&lt;/b&gt;&lt;br /&gt;wmic /node:%server% path win32_shadowstorage&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List VSS Max storage for disabled volumes&lt;/b&gt;&lt;br /&gt;reg query HKLM\System\CurrentControlSet\Services\VSS\Volumes\Associations\{00b810fd-8ab6-11de-9d34-806e6f6e6963}\{00b810fd-8ab6-11de-9d34-806e6f6e6963}\MaxDiffSpace&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Force a STOP error and generate a memory dump (Stop 0x2E) after enabling&lt;/b&gt;&lt;br /&gt;Right Ctrl+ScrollLock+ScrollLock&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable the option to generate a STOP error on demand&lt;/b&gt;&lt;br /&gt;reg add "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\i8042prt\Parameters /v CrashOnCtrlScroll /t reg_dword /d 0x1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Logoff a remote terminal sessions session (after using query.exe)&lt;/b&gt;&lt;br /&gt;logoff rdp-tcp#42 /v /server:%server%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the DLL function exports of the specified DLL&lt;/b&gt;&lt;br /&gt;dumpbin c:\temp\dllname.dll /exports&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Terminate a disconnected terminal services session&lt;/b&gt;&lt;br /&gt;rwinsta 0 /server:%server%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find memory information from a list of machines&lt;/b&gt;&lt;br /&gt;for /f %i in (computers.txt) do for /f "tokens=1-5" %m in ('"wmic /node:%i path Win32_PerfFormattedData_PerfOS_Memory get PoolNonpagedBytes,PoolPagedBytes,PoolPagedResidentBytes,FreeSystemPageTableEntries,AvailableMBytes &amp;#124; find /i /v "bytes""') do echo %i,%m,%n,%o,%p,%q&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the percentage at which the paged pool working set is trimmed&lt;/b&gt;&lt;br /&gt;reg add "\\%server%\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Memory Management" /v PoolUsageMaximum /t reg_dword /d 60&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Calculate a replication summary for the domain&lt;/b&gt;&lt;br /&gt;repadmin /replsum /bysrc /bydest /sort:delta&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check a 2008 R2 schema forest prep has run successfully (rvevision=5)&lt;/b&gt;&lt;br /&gt;dsquery * "CN=ActiveDirectoryUpdate,CN=ForestUpdates,CN=Configuration,domainRoot" -attr * -scope base&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check a 2008 R2 schema domain prep has run successfully (revision=5)&lt;/b&gt;&lt;br /&gt;dsquery * "CN=ActiveDirectoryUpdate,CN=DomainUpdates,CN=System,domainRoot" -attr * -scope base&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the infrastructure role holder for the DNS domain application partition&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Infrastructure,DC=DomainDNSZones,domainRoot" -attr fSMORoleOwner   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the application partitions from the forest root configuration NC&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Partitions,CN=Configuration,domainRoot" -filter "(&amp;(objectClass=crossRef)(msDS-SDReferenceDomain=*))" -attr ncName dnsRoot&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Monitor the page faults of an application (hard and soft)&lt;/b&gt;&lt;br /&gt;pfmon.exe c:\temp\application.exe&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Monitor the page faults of a process (hard and soft)&lt;/b&gt;&lt;br /&gt;psmon /p %PID%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reset the SystemPages memory management for available PTE's to server 2003 def.&lt;/b&gt;&lt;br /&gt;reg add "\\%server%\HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management" /v SystemPages /t reg_dword /d 0x0x&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find Exchange mailbox limits for user accounts&lt;/b&gt;&lt;br /&gt;csvde -f limits.csv -l samaccountname,cn,mDBStorageQuota,mDBOverQuotaLimit,mDBUseDefaults,mDBOverHardQuotaLimit,homeMDB -r "(&amp;(objectClass=User)(objectCategory=Person)(mailnickname=*))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find computer accounts not server, XP or Vista&lt;/b&gt;&lt;br /&gt;dsquery * domainroot -filter "(&amp;(objectCategory=Computer)(objectClass=Computer)(&amp;(!(operatingSystem=*prof*)(!(operatingSystem=*server*)(!(operatingSystem=*vista*))))))" -limit 0 -attr CN operatingSystem operatingSystemVersion&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SPNs from the directory&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(servicePrincipalName=*)" -attr cn servicePrincipalName -limit 0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query a list of groups and determine the group type (global/local/universal)&lt;/b&gt;&lt;br /&gt;dsquery group -name *groupfilter* &amp;#124; dsget group -scope -secgrp -dn&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Perform a NetBIOS name lookup&lt;/b&gt;&lt;br /&gt;nblookup %NETBIOS_NAME%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extract DNS scavenging events from the DNS eventlog&lt;/b&gt;&lt;br /&gt;wmic /node:"%server%" path Win32_NTLogEvent WHERE "SourceName='DNS' AND LogFile='DNS Server' AND EventCode=2501"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dump GPO information on priority and inherited links for an OU&lt;/b&gt;&lt;br /&gt;cscript DumpSOMInfo.wsf "OUName" /ShowInheritedLinks&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Copy a GPO &lt;/b&gt;&lt;br /&gt;cscript copygpo.wsf "Default Domain Policy" "Test Domain Policy" domain.com domain.com %SourceDC% %TargetDC%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Backup a number of GPOs from a control file input&lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (gpos.txt) do cscript backupgpo.wsf "%i" c:\temp\gpo&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a number of blank GPOs from a control file input         &lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (c:\temp\gpo.txt) do cscript CreateGPO.wsf "%i" /domain:domain.com&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add GPO permissions for a number of GPOs&lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (c:\temp\gpo.txt) do cscript SetGPOPermissions.wsf "%i" domain\user /permission:fulledit&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the available features for a 2008 R2 online installation &lt;/b&gt;&lt;br /&gt;dism /online /get-features&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Allow remote desktop connections on a 2008 R2 server (requires reboot)&lt;/b&gt;&lt;br /&gt;reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t reg_dword /d 0x0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Allow remote desktop connections on a 2008 R2 server core  (requires reboot)&lt;/b&gt;&lt;br /&gt;cscript C:\Windows\System32\Scregedit.wsf /ar 0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the boot timeout for a 2008 server&lt;/b&gt;&lt;br /&gt;bcdedit /timeout 5&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modify startup and recovery settings prevent automatic restart on 2008 server &lt;/b&gt;&lt;br /&gt;reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\CrashControl /v "AutoReboot" /t reg_dword /d 0x0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modify the performance options to adjust for best performance&lt;/b&gt;&lt;br /&gt;reg add HKU\.default\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects /v VisualFXSetting /t reg_dword /d 0x2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Disable hibernation on 2008 server&lt;/b&gt;&lt;br /&gt;powercfg -hibernate off&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Change the default user profile to adjust performance options for best perf&lt;/b&gt;&lt;br /&gt;reg load c:\users\Default\ntuser.dat &amp; reg add HKLM\a\Software\Microsoft\Windows\CurrentVersion\Explorer\VisualEffects /v VisualFXSetting /t reg_dword /d 0x2 &amp; reg unload hkml\a&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable boot logging on 2008 server&lt;/b&gt;&lt;br /&gt;bcdedit /set {default} bootlog yes  &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Disable Windows Error Reporting on 2008 server&lt;/b&gt;&lt;br /&gt;serverWerOptin /disable&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adjust windows server 2008 event log sizes to 128MB&lt;/b&gt;&lt;br /&gt;wevtutil sl Security /ms:135266304&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Install Windows Server 2008 R2 optional components (features and roles)&lt;/b&gt;&lt;br /&gt;cmd /c start /w ocsetup RSAT-NIS;SNMP;WMISnmpProvider;WindowsServerBackup;WindowsServerBackupCommandlet;NetFx3;MicrosoftWindowsPowerShellISE /quiet /norestart /log:c:\temp\install.log&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check Microsoft iSCSI initiator MaxRequestHoldTime &lt;/b&gt;&lt;br /&gt;reg query "\\%server%\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318}\0002\Parameters" /v MaxRequestHoldTime&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-1883751002856445189?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=1883751002856445189' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1883751002856445189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1883751002856445189'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2010/03/more-useful-command-lines.html' title='More useful command-lines'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-225980751523863587</id><published>2010-01-14T22:33:00.004+10:00</published><updated>2010-01-14T22:39:37.566+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>PowerCLI: Copy-VMGuestFile</title><content type='html'>In VMware PowerCLI Update 1, a new cmdlet has been added to copy files to/from guest OS’s using the VMTools. Under normal circumstances this wouldn’t be all that useful, but if a machine is not accessible on the network – either a DMZ or a test-lab environment for example – there is now a method to easily copy files to and from the guest machines.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;copy-vmguestfile -source c:\windows\system32\imageres.dll -destination c:\temp\ -vm vm01 -guesttolocal -hostuser root -hostpassword * -guestuser administrator -guestpassword *&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Note that you need to specify the passwords, or not specify credentials at all for a prompt, or you can use a pscredential object.&lt;br /&gt;&lt;br /&gt;Unfortunately wildcards are currently unsupported, but it would be easy to loop through local files within PowerShell to upload based on wildcards.&lt;br /&gt;&lt;br /&gt;I ran this with the measure-command cmdlet to see how fast it was – about 0.5MB/sec– not too quick, but a lot better than nothing.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;measure-command -expression {copy-vmguestfile -source c:\windows\system32\imageres.dll -destination c:\temp\ -vm vm01 -guesttolocal -hostuser root -hostpassword * -guestuser administrator -guestpassword *}&lt;br /&gt;&lt;br /&gt;Seconds : 26&lt;br /&gt;Milliseconds : 539&lt;br /&gt;Ticks : 265390633&lt;br /&gt;TotalDays : 0.000307165084490741&lt;br /&gt;TotalHours : 0.00737196202777778&lt;br /&gt;TotalMinutes : 0.442317721666667&lt;br /&gt;TotalSeconds : 26.5390633&lt;br /&gt;TotalMilliseconds : 26539.0633&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2010 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-225980751523863587?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=225980751523863587' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/225980751523863587'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/225980751523863587'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2010/01/powercli-copy-vmguestfile.html' title='PowerCLI: Copy-VMGuestFile'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-757435105170791359</id><published>2009-11-29T16:07:00.000+10:00</published><updated>2009-11-29T16:08:10.386+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>vCenter file copy with virtual floppy disk</title><content type='html'>n an ESXi or vCenter environment, without network connectivity to a virtual machine from your administrative workstation it's quite hard to bi-directionally transfer files.  &lt;br /&gt;&lt;br /&gt;This post discusses a simple method I use for small quick file transfer from a secure virtual machine to my administrative workstation, using virtual floppy drives managed from the command-line.&lt;br /&gt;&lt;br /&gt;This process uses vfd.exe, but presumably any virtual floppy software on your workstation could be used.  The virtual machine also needs to have a floppy drive...&lt;br /&gt;&lt;br /&gt;To bi-directionally transfer files from a non-network connected VM to my administrative workstation:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a virtual floppy disk on my workstation&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Mount that floppy disk file as a virtual floppy drive on my workstation as A:&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Through VI client, connect the VM to the A: drive &lt;/li&gt;&lt;br /&gt;&lt;li&gt;On the VM, copy files to/from A: drive and disconnect from the floppy&lt;/li&gt;&lt;br /&gt;&lt;li&gt;On my workstation, copy files to/from the virtual A:&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Close the virtual floppy&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Using vfd.exe:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;vfd install&lt;/li&gt;&lt;br /&gt;&lt;li&gt;vfd open c:\temp\new.flp&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use VI Client to connect to A:&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Copy files, then disconnect the VM virtual device&lt;/li&gt;&lt;br /&gt;&lt;li&gt;copy a:\*.*&lt;/li&gt;&lt;br /&gt;&lt;li&gt;vfd close&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;The obvious limitation of this is that the size is limited to 1.44MB.  I tried with a 2.44MB floppy and the virtual machine didn't recognise this disk.&lt;br /&gt;&lt;br /&gt;This doesn’t work with a virtual CD-ROM, as it’s mounted as read-only in the VM, so bi-directional copies aren’t available.  You can still use a similar process for creating an ISO to copy files into a VM though.  For this I use oscdimg.exe (Microsoft utility) to create my ISO from the command-line.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-757435105170791359?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=757435105170791359' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/757435105170791359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/757435105170791359'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/11/vcenter-file-copy-with-virtual-floppy.html' title='vCenter file copy with virtual floppy disk'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-23291412548493862</id><published>2009-10-30T23:14:00.003+10:00</published><updated>2009-10-31T23:07:18.846+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>VMware PowerCLI commands</title><content type='html'>The VMware PowerCLI PowerShell interface provided for managing vSphere systems is a fantastic tool that should be useful for all VMware admins.&lt;br /&gt;&lt;br /&gt;I've gathered these commands while implementing and managing ESXi 4.0 clusters, use with caution on any production system.&lt;br /&gt;&lt;br /&gt;This is an extension of a previous post:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2009/08/vmware-vsphere-powercli-commands.html"&gt;VMware vSphere PowerCLI commands&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Join a cluster by moving an ESX host from one location to the cluster&lt;/u&gt;&lt;br /&gt;Move-Inventory -Item (Get-VMHost -Name esxHost) -Destination (Get-Cluster -Name clusterName)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Get the VMware.Vim.ClusterComputeResource MO from the PowerCLI cluster object&lt;/u&gt;&lt;br /&gt;$clusterview = get-view $cluster.Id&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reconfigure a host for VMware HA (high availability)&lt;/u&gt;&lt;br /&gt;$vmhost = get-vmhost -name esxHost; $hostMO = Get-View -ID $vmhost.ID; $hostMO.ReconfigureHostForDAS()&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find migration events for the last day&lt;/u&gt;&lt;br /&gt;$events = Get-VIEvent -Start (Get-Date).AddDays(-1) &amp;#124; where {$_.fullFormattedMessage -match "Migrating.*"}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find events other than CPU Alarms or user login/logout for the last day&lt;/u&gt;&lt;br /&gt;$events = Get-VIEvent -Start (Get-Date).AddDays(-1) &amp;#124; where {$_.fullFormattedMessage -notmatch "Alarm.*CPU.*&amp;#124;User.*logged.*"}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find events for degraded MPIO path redundancy &lt;/u&gt;&lt;br /&gt;$events = Get-VIEvent -Start (Get-Date).AddDays(-1) &amp;#124; where {$_.fullFormattedMessage -match "Path redundancy to storage.*degraded"}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report the date, host and description for MPIO path redundancy errors&lt;/u&gt;&lt;br /&gt;foreach ($event in $events) {write-output ($event.createdTime.ToString() + "," + $event.host.get_name() + "," + $event.fullFormattedMessage)}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List a table of VI events with only the date and message&lt;/u&gt;&lt;br /&gt;$events &amp;#124; format-table -wrap -autosize -property createdTime,fullFormattedMessage&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List the physical networks adapters and the current link speed (ESX 4.0)&lt;/u&gt;&lt;br /&gt;$hostSystem = get-view -ViewType HostSystem; $hostConfigManager = $hostSystem.get_ConfigManager(); $hostNetworkSystem = $hostConfigManager.get_NetworkSystem(); $netSystem = Get-View $hostNetworkSystem; $netSystem.NetworkConfig.pnic; foreach ($pnic in  $netSystem.NetworkConfig.pnic) {Write-Output ($pnic.Device + "," + $pnic.spec.linkspeed.SpeedMB)}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List the vSwitches and the uplinks currently attached&lt;/u&gt;&lt;br /&gt;$hostSystem = get-view -ViewType HostSystem; $hostConfigManager = $hostSystem.get_ConfigManager(); $hostNetworkSystem = $hostConfigManager.get_NetworkSystem(); $netSystem = Get-View $hostNetworkSystem; foreach ($vswitch in  $netSystem.NetworkConfig.vSwitch) {Write-Output ($vSwitch.Name + "," + $vswitch.spec.policy.NicTeaming.NicOrder.ActiveNic)}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remove snapshots from a group of machines&lt;/u&gt;&lt;br /&gt;$VMs = Get-VM -Location (get-folder -name "vmFolder"); foreach ($vm in $vms) {remove-snapshot -snapshot (Get-Snapshot -vm $vm) -confirm:$false}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Take snapshots of a group of machines&lt;/u&gt;&lt;br /&gt;$VMs = Get-VM -Location (get-folder -name "vmFolder"); foreach ($vm in $VMs) {New-Snapshot -Name "snapshot 01" -description "Snapshot description" -vm $vm -Quiesce:$false}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find VM name, description and primary disk datastore&lt;/u&gt;&lt;br /&gt;$VMs = get-vm; foreach ($vm in $VMs) {write-output ($vm.Name + ",""" + $vm.Description + """," + $vm.harddisks[0].FileName.Replace(" ", ",")) &amp;#124; out-file -append -filepath c:\temp\VM_Datastores.txt}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Bring a host out of maintenance most&lt;/u&gt;&lt;br /&gt;Set-VMHost -VMHost esxHost -State Connected&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Generate diagnostic support bundles for all hosts&lt;/u&gt;&lt;br /&gt;get-log -vmhost (get-vmhost) -bundle -destinationpath c:\temp\bundles&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the network adapter type for each VM&lt;/u&gt;&lt;br /&gt;$vms = get-vm ; foreach ($vm in $vms) {write-host $vm.Name "-"  $vm.networkadapters[0].type}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find physical NICs and whether they're set to autonegotiate or hardcoded&lt;/u&gt;&lt;br /&gt;foreach ($pnic in $hostNetwork.pnic) {if($pnic.linkSpeed -eq $null) {$ls = "Auto"} else {$ls= $pnic.linkSpeed.speedMB.toString() + ":" + $pnic.linkSpeed.duplex} ;write-output ($pnic.Device + "," + $ls)}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find host sytem build information&lt;/u&gt;&lt;br /&gt;$hostSystems = get-view -ViewType HostSystem; foreach ($hostSystem in $hostSystems) {Write-Output ($hostSystem.Name + "," + $hostSystem.config.product.Fullname)}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find VMs and whether the VMtools is configured to synchronising time &lt;/u&gt;&lt;br /&gt;$vmSet = Get-VM ; foreach ($vm in $vmSet) { $view = get-view $vm.ID ;$config = $view.config; $tools = $config.tools; Write-Output ($vm.Name + "," + $tools.SyncTimeWithHost) }&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Revert to a snapshot&lt;/u&gt;&lt;br /&gt;set-vm -vm vmName -snapshot (get-snapshot -vm vmName) -confirm:$false&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remove a virtual machine from inventory and delete from disk&lt;/u&gt;&lt;br /&gt;remove-vm -DeleteFromDisk:$true -RunAsync:$true -vm vmName&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Shutdown one or more Virtual Machine guests&lt;/u&gt;&lt;br /&gt;shutdown-vmguest -vm $vms -confirm:$false&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Start one or more Virtual Machine guests&lt;/u&gt;&lt;br /&gt;start-vm -vm $vms -confirm:$false&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Forcefully power off one or more Virtual Machines&lt;/u&gt;&lt;br /&gt;stop-vm $vms -confirm:$false&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Get a virtual switch from the specified ESX host&lt;/u&gt;&lt;br /&gt;get-virtualswitch -name vSwitch1 -vmhost esxHost&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a new port group on the specified vSwitch&lt;/u&gt;&lt;br /&gt;New-VirtualPortGroup -Name "pgName" -VirtualSwitch $vs&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find ESX memory balloon averages for the last five days&lt;/u&gt;&lt;br /&gt;get-stat -entity $hosts -start (Get-Date).AddDays(-5) -finish (Get-Date) -stat mem.vmmemctl.average&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Export a list of VMs&lt;/u&gt;&lt;br /&gt;$vms &amp;#124; select-object -prop Name &amp;#124; out-file -filepath c:\temp\vms.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Export a list of VM guest hostnames &lt;/u&gt;&lt;br /&gt;$vms = get-vm; foreach ($vm in $vms) { write-output $vm.guest.get_HostName()}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-23291412548493862?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=23291412548493862' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/23291412548493862'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/23291412548493862'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/10/vmware-powercli-commands.html' title='VMware PowerCLI commands'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-831767988099752242</id><published>2009-10-13T22:38:00.000+10:00</published><updated>2009-10-13T22:38:03.989+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><title type='text'>Service Control Manager Security for non-admins</title><content type='html'>Allowing non-administrators rights for service control sounds deceptively simple, but unfortunately it’s not.  After Windows Server 2003 SP1, the default rights are very focused on administrator-only access for service control.&lt;br /&gt;&lt;br /&gt;This post describes how to view and modify the security descriptor for the Service Control Manager (SCM) and individual services as required.&lt;br /&gt;&lt;br /&gt;Show the descriptor for SCM:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sc sdshow SCMANAGER&lt;br /&gt;&lt;br /&gt;D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this case, the output shows that by default, Authenticated Users (AU) only have connect, but not enumerate (LC) for SCM.&lt;br /&gt;&lt;br /&gt;If you want to allow a non-administrator to connect to the Service Control Manager and enumerate the services, you can modify the security descriptor by using something like the following command to add enumerate, read control and query lock status for Authenticated Users with SCM:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;sc sdset SCMANAGER&lt;br /&gt;&lt;br /&gt;D:(A;;CCLCRPRC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This allows connecting to the SCM and enumerating services.  However, if the DACL on the individual services only allows administrators access to the services, then they still won’t be accessible.  You’ll need to run specific 'sc sdset' commands against particular services, or use subinacl to change all services with one command.&lt;br /&gt;&lt;br /&gt;Note that the sc.exe version with XP does not support this syntax – use the sc.exe on 2003 server.&lt;br /&gt;&lt;br /&gt;For individual services, you could then allow query and interrogate with the following command:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;subinacl /service \\server\* /grant=domain\user=QSI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that to map the ACE flags to the meaning with regards to service control, I went through the following process:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Find the access rights from the flag, eg CC = SDDL_CREATE_CHILD = ADS_RIGHT_DS_CREATE_CHILD (ACE Strings link below)&lt;/li&gt;&lt;li&gt;Find the constant matching this value, eg. 0x1 (ADS_RIGHTS_ENUM Enumeration link below)&lt;/li&gt;&lt;li&gt;Match this to the SCM access right for the hexadecimal value, eg. 0x1 = SC_MANAGER_CONNECT (Service Security and Access Rights link below)&lt;/li&gt;&lt;/ol&gt;Map between sdshow output, right, hex value and SC/service meaning:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;"CC"  ADS_RIGHT_DS_CREATE_CHILD          = 0x1,    SC_MANAGER_CONNECT, SERVICE_QUERY_CONFIG&lt;br /&gt;"DC"  ADS_RIGHT_DS_DELETE_CHILD          = 0x2,    SC_MANAGER_CREATE_SERVICE, SERVICE_CHANGE_CONFIG&lt;br /&gt;"LC"  ADS_RIGHT_ACTRL_DS_LIST            = 0x4,    SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_STATUS&lt;br /&gt;"SW"  ADS_RIGHT_DS_SELF                  = 0x8,    SC_MANAGER_LOCK, SERVICE_ENUMERATE_DEPENDENTS&lt;br /&gt;"RP"  ADS_RIGHT_DS_READ_PROP             = 0x10,   SC_MANAGER_QUERY_LOCK_STATUS, SERVICE_START, &lt;br /&gt;"WP"  ADS_RIGHT_DS_WRITE_PROP            = 0x20,   SC_MANAGER_MODIFY_BOOT_CONFIG, SERVICE_STOP&lt;br /&gt;"DT"  ADS_RIGHT_DS_DELETE_TREE           = 0x40,   SERVICE_PAUSE_CONTINUE&lt;br /&gt;"LO"  ADS_RIGHT_DS_LIST_OBJECT           = 0x80,   SERVICE_INTERROGATE&lt;br /&gt;"CR"  ADS_RIGHT_DS_CONTROL_ACCESS        = 0x100   SERVICE_USER_DEFINED_CONTROL&lt;br /&gt;"RC"  READ_CONTROL                       = 0x20000 READ_CONTROL&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Access right Description for services and SCM:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;SERVICE_QUERY_CONFIG (0x0001) Required to call the QueryServiceConfig and QueryServiceConfig2 functions to query the service configuration. &lt;br /&gt;SERVICE_CHANGE_CONFIG (0x0002) Required to call the ChangeServiceConfig or ChangeServiceConfig2 function to change the service configuration. Because this grants the caller the right to change the executable file that the system runs, it should be granted only to administrators.  &lt;br /&gt;SERVICE_QUERY_STATUS (0x0004) Required to call the QueryServiceStatusEx function to ask the service control manager about the status of the service. &lt;br /&gt;SERVICE_ENUMERATE_DEPENDENTS (0x0008) Required to call the EnumDependentServices function to enumerate all the services dependent on the service. &lt;br /&gt;SERVICE_START (0x0010) Required to call the StartService function to start the service. &lt;br /&gt;SERVICE_STOP (0x0020) Required to call the ControlService function to stop the service. &lt;br /&gt;SERVICE_PAUSE_CONTINUE (0x0040) Required to call the ControlService function to pause or continue the service. &lt;br /&gt;SERVICE_INTERROGATE (0x0080) Required to call the ControlService function to ask the service to report its status immediately. &lt;br /&gt;SERVICE_USER_DEFINED_CONTROL(0x0100) Required to call the ControlService function to specify a user-defined control code. &lt;br /&gt;SERVICE_ALL_ACCESS (0xF01FF) Includes STANDARD_RIGHTS_REQUIRED in addition to all access rights in this table. &lt;br /&gt;READ_CONTROL Required to call the QueryServiceObjectSecurity function to query the security descriptor of the service object. &lt;br /&gt;&lt;br /&gt;SC_MANAGER_CONNECT (0x0001) Required to connect to the service control manager. &lt;br /&gt;SC_MANAGER_CREATE_SERVICE (0x0002) Required to call the CreateService function to create a service object and add it to the database. &lt;br /&gt;SC_MANAGER_ENUMERATE_SERVICE (0x0004) Required to call the EnumServicesStatusEx function to list the services that are in the database. &lt;br /&gt;SC_MANAGER_LOCK (0x0008) Required to call the LockServiceDatabase function to acquire a lock on the database. &lt;br /&gt;SC_MANAGER_QUERY_LOCK_STATUS (0x0010) &lt;br /&gt;SC_MANAGER_MODIFY_BOOT_CONFIG (0x0020) Required to call the NotifyBootConfigStatus function. &lt;br /&gt;SC_MANAGER_ALL_ACCESS (0xF003F) Includes STANDARD_RIGHTS_REQUIRED, in addition to all access rights in this table. &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Directory service object access rights&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;"RC"  SDDL_READ_CONTROL  READ_CONTROL &lt;br /&gt;"RP"  SDDL_READ_PROPERTY  ADS_RIGHT_DS_READ_PROP  &lt;br /&gt;"WP"  SDDL_WRITE_PROPERTY  ADS_RIGHT_DS_WRITE_PROP  &lt;br /&gt;"CC"  SDDL_CREATE_CHILD  ADS_RIGHT_DS_CREATE_CHILD  &lt;br /&gt;"DC"  SDDL_DELETE_CHILD  ADS_RIGHT_DS_DELETE_CHILD  &lt;br /&gt;"LC"  SDDL_LIST_CHILDREN  ADS_RIGHT_ACTRL_DS_LIST  &lt;br /&gt;"SW"  SDDL_SELF_WRITE  ADS_RIGHT_DS_SELF  &lt;br /&gt;"LO"  SDDL_LIST_OBJECT  ADS_RIGHT_DS_LIST_OBJECT  &lt;br /&gt;"DT"  SDDL_DELETE_TREE  ADS_RIGHT_DS_DELETE_TREE  &lt;br /&gt;"CR"  SDDL_CONTROL_ACCESS  ADS_RIGHT_DS_CONTROL_ACCESS  &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ADS enum:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;typedef enum  {&lt;br /&gt;  ADS_RIGHT_DS_CREATE_CHILD          = 0x1,&lt;br /&gt;  ADS_RIGHT_DS_DELETE_CHILD          = 0x2,&lt;br /&gt;  ADS_RIGHT_ACTRL_DS_LIST            = 0x4,&lt;br /&gt;  ADS_RIGHT_DS_SELF                  = 0x8,&lt;br /&gt;  ADS_RIGHT_DS_READ_PROP             = 0x10,&lt;br /&gt;  ADS_RIGHT_DS_WRITE_PROP            = 0x20,&lt;br /&gt;  ADS_RIGHT_DS_DELETE_TREE           = 0x40,&lt;br /&gt;  ADS_RIGHT_DS_LIST_OBJECT           = 0x80,&lt;br /&gt;  ADS_RIGHT_DS_CONTROL_ACCESS        = 0x100 &lt;br /&gt;&lt;br /&gt;} ADS_RIGHTS_ENUM;&lt;br /&gt;&lt;br /&gt;READ_CONTROL = 0x20000;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;Applying Security Descriptors on the Device Object&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms793368.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms793368.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Non-administrators cannot remotely access the Service Control Manager after you install Windows Server 2003 Service Pack 1&lt;br /&gt;&lt;a href="http://support.microsoft.com/default.aspx?scid=kb;EN-US;907460"&gt;http://support.microsoft.com/default.aspx?scid=kb;EN-US;907460&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Securing a Remote WMI Connection&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa393266(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/aa393266(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Configuring a Report Server for Remote Administration&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms365170(SQL.90).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms365170(SQL.90).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Service Security and Access Rights&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms685981(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms685981(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How to grant users rights to manage services in Windows 2000&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/288129"&gt;http://support.microsoft.com/kb/288129&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How to troubleshoot WMI-related issues in Windows XP SP2&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/875605"&gt;http://support.microsoft.com/kb/875605&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ACE Strings&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa374928(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/aa374928(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ADS_RIGHTS_ENUM Enumeration&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa772285(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/aa772285(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-831767988099752242?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=831767988099752242' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/831767988099752242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/831767988099752242'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/10/service-control-manager-security-for.html' title='Service Control Manager Security for non-admins'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3763124935112509299</id><published>2009-09-30T23:03:00.002+10:00</published><updated>2009-09-30T23:05:29.880+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>VMware Command-Line Interface commands</title><content type='html'>The Windows command-line interface provided for managing ESX/ESXi systems is an invaluable tool for managing ESX infrastructure at the command-line.  When using ESXi without a service console the CLI becomes even more useful.&lt;br /&gt;&lt;br /&gt;I've gathered these commands while implementing and managing ESXi 4.0 clusters, use with caution on any production system.&lt;br /&gt;&lt;br /&gt;ESXi 4.0 RCLI:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;b&gt;List the NTP servers used by the host&lt;/b&gt;&lt;br /&gt;vicfg-ntp.pl --server esx01 --list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add a Software iSCSI NIC named vmk2&lt;/b&gt;&lt;br /&gt;esxcli --server=esx01 swiscsi nic add -n vmk2 -d vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the Software iSCSI NICs&lt;/b&gt;&lt;br /&gt;esxcli --server=esx01 swiscsi nic list -d vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the software iSCSI status on a host&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --swiscsi --list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable software iSCSI on an ESX host&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --swiscsi --enable&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the adapters bound to software iSCSI&lt;/b&gt;&lt;br /&gt;esxcli --server=esx01 swiscsi nic list -d vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the VMKernel NICs&lt;/b&gt;&lt;br /&gt;vicfg-vmknic.pl --server esx01 --list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the software iSCSI adapters&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --adapter --list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the iSCSI alias for the specified adapter&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --iscsiname --alias esx01 vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bind a VMK software iSCSI NIC for MPIO PSA&lt;/b&gt;&lt;br /&gt;esxcli --server=esx01 swiscsi nic add -n vmk2 -d vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Rescan a storage adapter bus&lt;/b&gt;&lt;br /&gt;vicfg-rescan.pl --server esx01 vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add a dynamic iSCSI discovery target&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --discovery --add --ip 10.1.1.10:3260 vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add CHAP authentication to an iSCSI discovery target&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --authentication --level chapRequired --method CHAP --auth_username esxchap --auth_password chapacc3ss80 --ip 10.2.128.33:3260 vmhba33&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the current ScratchConfig scratch location&lt;/b&gt;&lt;br /&gt;vicfg-advcfg.pl --server esx01 -g ScratchConfig.ConfiguredScratchLocation&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the scratch location for ESXi&lt;/b&gt;&lt;br /&gt;vicfg-advcfg.pl --server esx01 -s "/vmfs/volumes/esxds01/Scratch/esx01" ScratchConfig.ConfiguredScratchLocation&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check if CIM OEM providers are enabled (such as Dell OM)&lt;/b&gt;&lt;br /&gt;vicfg-advcfg.pl --server esx01 -g UserVars.CIMOEMProvidersEnabled&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable CIM OEM Providers (such as Dell OM)&lt;/b&gt;&lt;br /&gt;vicfg-advcfg.pl --server esx01 -s "1" UserVars.CIMOEMProvidersEnabled&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the patches/updates/bulletins/VIBs installed on ESXi&lt;/b&gt;&lt;br /&gt;vihostupdate.pl --server esx01 -q&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the SNMP community for the ESXi host&lt;/b&gt;&lt;br /&gt;vicfg-snmp.pl --server esx01 -c public&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable the SNMP agent on an ESXi host&lt;/b&gt;&lt;br /&gt;vicfg-snmp.pl --server esx01 -E&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the iSCSI node name&lt;/b&gt;&lt;br /&gt;vicfg-iscsi.pl --server esx01 --list --iscsiname --adapter vmhba36&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the preferred nativte multipathing (NMP) path for a device&lt;/b&gt;&lt;br /&gt; esxcli --server esx01 nmp fixed getpreferred -d naa.6090332880cfdc44fda634b1ca2457b8&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check whether round robin path selection is used for a device&lt;/b&gt;&lt;br /&gt;esxcli --server esx01 nmp roundrobin getconfig -d naa.6090a02833cfdc7ffd4434b1ca5457b8 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the disk NAA/UUIDs known to a host&lt;/b&gt;&lt;br /&gt;esxcli --server esx01 nmp device list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the MPIO path to device mapping&lt;/b&gt;&lt;br /&gt;esxcfg-mpath.pl --server esx01 -m&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the SCSI devices known to a host&lt;/b&gt;&lt;br /&gt;vicfg-scsidevs.pl --server esx01 --list   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the available datastores on a host&lt;/b&gt;&lt;br /&gt;vifs.pl --server esx01 --listds&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the contents of a datastore&lt;/b&gt;&lt;br /&gt; vifs.pl --server esx01 --dir [datastore]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Upload a local file to a datastore through vifs&lt;/b&gt;&lt;br /&gt;vifs.pl --server esx01 --put c:\temp\file.txt dir/file.txt?dsName=datastoreName&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List virtual switches, port groups, uplinks and MTU&lt;/b&gt;&lt;br /&gt;vicfg-vswitch.pl -l --server esx01&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Browse the datastores or local host through ssl&lt;/b&gt;&lt;br /&gt;https://esx01/folder or https://esx01/host&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the vmnic configuration, including driver, current speed&lt;/b&gt;&lt;br /&gt;vicfg-nics.pl --server esx01 -l &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set a vNIC to auto-negotiate&lt;/b&gt;&lt;br /&gt;vicfg-nics.pl --server esx01 --vihost esx01 -a vmnic0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the host-based files on an ESXi client&lt;/b&gt;&lt;br /&gt;vifs.pl --server esx01 --dir /host  &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A few other useful VMware tips:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;b&gt;Recreate the rui.pfx file for VirtualCenter&lt;/b&gt;&lt;br /&gt;openssl pkcs12 -export -in rui.crt -inkey rui.key -name rui -passout pass:testpassword -out rui.pfx&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Forcefully power off a suspended VM&lt;/b&gt;&lt;br /&gt;Delete the vmss file, and then power on the VM (state is lost)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ESXi 4.0, access unsupported ssh console through the dcui&lt;/b&gt;&lt;br /&gt;Press Alt+F1, type unsupported, then the root password&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3763124935112509299?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3763124935112509299' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3763124935112509299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3763124935112509299'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/09/vmware-command-line-interface-commands.html' title='VMware Command-Line Interface commands'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-40197023012568785</id><published>2009-09-20T23:57:00.000+10:00</published><updated>2009-09-20T23:57:15.153+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><title type='text'>More useful command-lines</title><content type='html'>This is the second edition of useful command lines, adding another 132 commands that I've found useful.  Note that many of the command-line calls may require Microsoft utilities (such as dsquery, wmic, dnscmd).&lt;br /&gt;&lt;br /&gt;Most of the commands are for the windows-based command interpreter, with a few PowerShell and ESX service console commands creeping in.  They range from diagnostics, troubleshooting and simply automating recurring tasks.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;br /&gt;See the original post with another 425 commands &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given an IP and mask, return the subet the IP belongs to&lt;/b&gt;&lt;br /&gt;for /f "tokens=1-8 delims=.- " %i in ('echo 192.168.5.200 255.255.255.0') do set /a Octet1="%i &amp; %m" &amp;gt;nul &amp; set /a Octet2="%j &amp; %n" &amp;gt;nul &amp; set /a Octet3="%k &amp; %o" &amp;gt;nul &amp; set /a Octet4="%l &amp; %p" &amp;gt;nul &amp; Echo %i.%j.%k.%l,!Octet1!.!Octet2!.!Octet3!.!Octet4!,%m.%n.%o.%p&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Display the contents of the client DNS resolver cache&lt;/b&gt;&lt;br /&gt;ipconfig /displaydns&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the package source path of a program from SMS&lt;/b&gt;&lt;br /&gt;wmic /namespace:\\root\sms\site_%sitecode% /node:"server" path SMS_Package Where "Name like '%programname%'" get Name,ShareName,PkgSourcePath&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the session associated with a process&lt;/b&gt;&lt;br /&gt;wmic path win32_process get name,sessionid&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the local winstation windows objects&lt;/b&gt;&lt;br /&gt;objdir \Windows\Windowstations\Winsta0&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the configuration container for Exchange mailbox stores&lt;/b&gt;&lt;br /&gt;dsquery * ",CN=Configuration,DC=domainroot" -filter "(&amp;(objectClass=msExchPrivateMDB)(objectCategory=msExchPrivateMDB))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query a Virtual Centre/VC 2.5 database for Virtual Machine details&lt;/b&gt;&lt;br /&gt;sqlcmd -S server -d database -W -s "," -Q "select ENT.Name as 'Name', Lower(DNS_Name) as 'DNS Name', Guest_OS as 'OS', Mem_Size_MB as 'Mem', Num_VCPU as 'CPU', Num_NIC as 'NIC', IP_Address as 'IP', NET.MAC_Address as 'MAC Address', VM.FILE_Name as 'VMX location' from vpx_vm VM inner join VPX_NIC NET on VM.ID = NET.ENTITY_ID inner join VPX_ENTITY ENT on VM.ID = ENT.ID Order By ENT.Name"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query a Virtual Centre/VC 2.5 database for Virtual Machine snapshots (GMT+10)&lt;/b&gt;&lt;br /&gt;sqlcmd -S server -d database -W -s "," -Q "select ENT.Name as 'Name', Lower(DNS_Name) as 'DNS Name', Guest_OS as 'OS', Mem_Size_MB as 'Mem', IP_Address as 'IP', VM.FILE_Name as 'VMX location', VM.Suspend_Time as 'Suspend Time', VM.Suspend_Interval as 'Suspend Interval', VMS.Snapshot_Name as 'Snapshot Name', VMS.Snapshot_Desc 'Snapshot Description', DateAdd(Hour, 10, VMS.Create_Time) as 'Snapshot Time', VMS.Is_Current_Snapshot 'Current Snapshot' from vpx_vm VM inner join VPX_NIC NET on VM.ID = NET.ENTITY_ID inner join VPX_ENTITY ENT on VM.ID = ENT.ID inner join VPX_SNAPSHOT VMS on VM.ID = VMS.VM_ID"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test the password for a domain account (assumes no existing IPC connection)&lt;/b&gt;&lt;br /&gt;net use \\server\ipc$ /user:%domain%\%testuser% *&lt;br /&gt;&lt;br /&gt;&lt;b&gt;View the last-access, modified, created and MFT entry modified timestampes&lt;/b&gt;&lt;br /&gt;timestomp "%fullpathtoFile%" -v&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a scheduled task escaped with a command containing double-quotes (2003)&lt;/b&gt;&lt;br /&gt;schtasks /create /SC Daily /TN "Task" /ST 12:00 /TR "cmd /c echo \"Test\"" /RU System&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a scheduled task running two commands&lt;/b&gt;&lt;br /&gt;schtasks /create /SC Daily /TN "Task" /ST 12:00 /TR "cmd /c echo Test1 &amp; cmd /c echo Test2" /RU System&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check a number of computers to see if hibernation is enabled&lt;/b&gt;&lt;br /&gt;for /f %i in (%controlfile%.txt) do @if exist \\%~i\c$\hiberfil.sys (echo %~i,Enabled) else (echo %~i,Disabled)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;For each path in a control file, list the 8.3 short equivalent&lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (test.txt) do echo %~si&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use if exist and disabled path parsing to bypass max_path&lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (test.txt) do if exist "\\?\UNC\%~pnxi" echo File exists&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enumerate a cluster through WMI&lt;/b&gt;&lt;br /&gt;wmic /node:"%node%" /namespace:\\root\mscluster path MSCluster_Cluster&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given a path exceeding MAX_PATH, return the 8.3 equivalent of the directories&lt;/b&gt;&lt;br /&gt;for /f "tokens=*" %i in (longfiles.txt) do for /d %m in ("\\%~pi") do echo %~sm%~nxi&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given a path you know contains deeper than 260, batch to return the 8.3 subdirs&lt;/b&gt;&lt;br /&gt;(3 lines) @for /f "tokens=*" %%i in (c:\temp\longdir1.txt) do @for /d %%m in ("\\%%~pi") do @Call :Process "%%~si" &amp;#124;&amp;#124; :process &amp;#124;&amp;#124; @if "%~1"=="" (goto :EOF) else (@for /d %%i in ("%~1\*.*") do @echo %%~si &amp; Call :Process "%%~si")&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set a Domain Controller to be a Global Catalog server&lt;/b&gt;&lt;br /&gt;dsmod server "%DC_DN%" -isgc yes&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check which network connections (drive mappings) a computer has&lt;/b&gt;&lt;br /&gt;wmic /node:"%computer%" path win32_logicaldisk where "DriveType=4" get DeviceID,ProviderName &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the current site of a remote computer using nltest&lt;/b&gt;&lt;br /&gt;nltest /dsgetsite /server:%computer%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the current site of a remote computer using the registry&lt;/b&gt;&lt;br /&gt;reg query \\%computer%\hklm\system\currentcontrolset\services\netlogon\parameters /v DynamicSiteName&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check the schema version on a Domain Controller (R2=31)&lt;/b&gt;&lt;br /&gt;reg query \\%dc%\hklm\system\currentcontrolset\services\NTDS\parameters /v "Schema Version"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the revision of 2003 Update (R2=9)&lt;/b&gt;&lt;br /&gt;dsquery * CN=Windows2003Update,CN=ForestUpdates,CN=Configuration,%forestRoot% -attr revision&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check the schema version on a Domain Controller (R2=31)&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Schema,CN=Configuration,%forestRoot%" -attr objectVersion -scope base   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the disk signature of a disk through diskpart&lt;/b&gt;&lt;br /&gt;echo select disk 0 &amp;gt; %temp%\diskpart.txt &amp; echo detail disk &amp;gt;&amp;gt; %temp%\diskpart.txt &amp; diskpart /s %temp%\diskpart.txt &amp;#124; find /i "Disk ID:"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Search a dnscmd export for duplicate IP address references&lt;/b&gt;&lt;br /&gt;for /f "tokens=1,5" %i in (DNSExport.txt) do @if "%j" NEQ "" @for /f "tokens=1" %m in ('"findstr /i "%j$" DNSExport.txt find /i /c "%j""') do @if %m GTR 1 @echo %i,%j,%m&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Search and report duplicate IPs from a dnscmd export&lt;/b&gt;&lt;br /&gt;for /f "tokens=1,4" %i in (DNSExport.txt) do @if "%j" NEQ "" @for /f "tokens=1" %m in ('"findstr /i "%j$" DNSExport.txt find /i /c "%j""') do @if %m GTR 1 (@echo %j,%m: &amp; findstr /i "%j$" DNSExport.txt &amp; echo.)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Dump the dfsr config from the active directory&lt;/b&gt;&lt;br /&gt;dfsrdiag dumpadcfg&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Remove Outlook 2003 prevention of PST usage&lt;/b&gt;&lt;br /&gt;reg add HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\11.0\Outlook /v DisablePST /t reg_dword /d 0x0 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the command prompt to include the time of the last command&lt;/b&gt;&lt;br /&gt;prompt $t $p$g&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a zero byte file&lt;/b&gt;&lt;br /&gt;echo file 2&amp;gt;zero.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Given a list of files, echo those that are zero bytes in size&lt;/b&gt;&lt;br /&gt;for %i in (%source%\*) do @if %~zi == 0 @echo %i&lt;br /&gt;&lt;br /&gt;&lt;b&gt;From a dnscmd export, find duplicate IP addresses&lt;/b&gt;&lt;br /&gt;echo. &amp;gt; DuplicateIPs.txt &amp; (for /f "tokens=1,4" %i in (DNSRecords.txt) do @if "%j" NEQ "" @find /i "%j" DuplicateIPs.txt &amp;gt;nul &amp; if errorlevel 1 for /f "tokens=1" %m in ('"findstr /i "%j$" DNSRecords.txt &amp;#124; find /i /c "%j""') do @if %m GTR 1 (@echo %j,%m: &amp; findstr /i "%j$" DNSRecords.txt &amp; echo.) &amp;gt;&amp;gt; DuplicateIPs.txt) &amp; type DuplicateIPs.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Start xperf performance tracing using the 'Diag' group&lt;/b&gt;&lt;br /&gt;xperf -start -on Diag -f %temp%\tracing.etl &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Open an xperf trace, exporting context switching for threads and processes&lt;/b&gt;&lt;br /&gt;xperf -i %temp%\tracing.etl -a cswitch -thread -process&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check whether VMware VMFS partitions are block aligned to 128&lt;/b&gt;&lt;br /&gt;/sbin/fdisk -lu&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query a Virtual Centre/VC 2.5 database for Consolidation performance stats&lt;/b&gt;&lt;br /&gt;sqlcmd -S server -d virtualcenter -W -s "," -Q "Select Top 6 ip_address as 'IP', cpu_mhz_avg/1000 as 'CPU', mem_mb_avg/1000 as 'RAM' , disk_percent_avg/1000 as 'Disk' from vpx_csl_system_perf vPERF inner join vpx_csl_system_ip_address vIP on vPERF.System_ID = vIP.system_ID order by sample_time desc"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Identify Virtual Machines that are currently powered on&lt;/b&gt;&lt;br /&gt;/usr/sbin/vcbVmName -h %server% -u username -s powerstate:on&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find OCS 2007 classes/attributes in AD&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Schema,CN=Configuration,DC=forestRoot" -filter "(&amp;((cn=*rtc*)(&amp;#124;(objectCategory=classSchema)(objectCategory=attributeSchema))))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find OCS 2007 server from DNS service records&lt;/b&gt;&lt;br /&gt;nslookup -type=srv _SipInternalTLS._tcp.{FQDN}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find OCS 2007 Pools published in the current directory&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(objectClass=msRTCSIP-Pools)"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find OCS 2007 SCPs from the local domain&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Pools,CN=RTC Service,CN=Microsoft,CN=System,DC=domainRoot" -attr *&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Export config from OCS 2007 from a remote server&lt;/b&gt;&lt;br /&gt;lcscmd /config /action:export /level:machine /configfile:config.xml /fqdn:%server%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IIS Authentication and Access Control Diagnostics&lt;/b&gt;&lt;br /&gt;authdiag.exe&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the number of VMs per datastore from the VC database&lt;/b&gt;&lt;br /&gt;sqlcmd -S server -d virtualcenter -W -s "," -Q "select DS.name, Count(VMDS.VM_ID) as 'VMs' from vpxv_vm_datastore VMDS inner join vpx_datastore DS on VMDS.DS_ID = DS.ID group by DS.name" &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find detail on the VMs per datastore from the VC database&lt;/b&gt;&lt;br /&gt;sqlcmd -S server -d virtualcenter -W -s "," -Q "select DS.name, VMS.Name from vpxv_vm_datastore VMDS inner join vpx_datastore DS on VMDS.DS_ID = DS.ID inner join vpxv_vms VMS on VMDS.VM_ID = VMS.VMID order by DS.Name"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Unattended install of IIS (assuming INF created with relevant [components])&lt;/b&gt;&lt;br /&gt;Sysocmgr.exe /i:%windir%\inf\sysoc.inf /u:%iisComponents%.inf&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the Exchange 2003 organization from AD&lt;/b&gt;&lt;br /&gt;dsquery * forestroot -filter "(&amp;(objectCategory=msExchOrganizationContainer))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mount a virtual floppy&lt;/b&gt;&lt;br /&gt;vfd install &amp; vfd start &amp; vfd open&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Send an SMTP mail using blat&lt;/b&gt;&lt;br /&gt;blat -f smtprelay@relay.local -to user@domain.com -subject Test -body "Test body" -server smtprelay&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create MAPI profiles with an Exchange connection on a server without Outlook&lt;/b&gt;&lt;br /&gt;profman2.exe&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find mailboxes that are excluded from Recipient Update Policies&lt;/b&gt;&lt;br /&gt;dsquery * -filter "(&amp;(objectClass=User)(objectCategory=Person)(msExchPoliciesExcluded=*))" -attr cn msExchPoliciesExcluded &amp;#124; find /i "{26491CFC-9E50-4857-861B-0CB8DF22B5D7}"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Export a connector space from MIIS/IIFP to XML&lt;/b&gt;&lt;br /&gt;csexport %maName% maExport.xml&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IIFP permissions, write proxyAddresses to user objects, inherited to subobjects&lt;/b&gt;&lt;br /&gt;dsacls "OU=%targetOU%,%domainRoot%" /I:S /G %DOMAIN%\%GROUP%:WP;proxyAddresses;user&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IIFP permissions, create and delete contact objects, inherited to subobjects&lt;/b&gt;&lt;br /&gt;dsacls "OU=%targetOU%,%domainRoot%" /I:S /G %DOMAIN%\%GROUP%:CCDC;contact&lt;br /&gt;&lt;br /&gt;&lt;b&gt;IIFP permissions, read/write all properties, inherited to subobjects&lt;/b&gt;&lt;br /&gt;dsacls "OU=%targetOU%,%domainRoot%" /I:S /G %DOMAIN%\%GROUP%:RPWP;;contact&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find extended rights in the directory that apply to schema classes&lt;/b&gt;&lt;br /&gt;dsquery * "CN=Extended-Rights,CN=Configuration,dc=forestRoot" -attr displayName CN&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Trigger the SD propagator adminsdholder process in a domain&lt;/b&gt;&lt;br /&gt;admod -rootdse "FixUpInheritance::1"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set interrupt processor affinity for PnP drivers&lt;/b&gt;&lt;br /&gt;intfiltr.exe&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set interrupt processor affinity for processes persistent across reboots&lt;/b&gt;&lt;br /&gt;imagecfg.exe -a 0xF calc.exe (the mask to use the first four logical processors)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Start an executable with the specified processor affinity&lt;/b&gt;&lt;br /&gt;start /affinity f calc.exe (the mask to use the first four logical processors)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modify a server to use only one processor&lt;/b&gt;&lt;br /&gt;boot.ini, add /onecpu switch&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query DC/DNS servers and find unconditional non-ds forwarders&lt;/b&gt;&lt;br /&gt;for /f %i in ('dsquery server -domain %userdnsdomain% -o rdn') do @for /f "tokens=1,3" %m in ('"dnscmd %i /info &amp;gt; DNS_%i.txt &amp; tail -5 DNS_%i.txt &amp;#124; find /i "addr[" &amp;#124; find /i "addr""') do @echo %~ni,%m,%n&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create an Active Directory integrated DNS conditional forwarder (5.2.3790.0)&lt;/b&gt;&lt;br /&gt;dnscmd /ZoneAdd %targetDomain% /DsForwarder %targetDomainNSIP%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find DNS forwarder zones&lt;/b&gt;&lt;br /&gt;dnscmd %server% /enumzones /forwarder&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find DNS forwarder targets&lt;/b&gt;&lt;br /&gt;for /f %i in ('"dnscmd %server% /enumzones /forwarder &amp;#124; find /i "forwarder""') do dnscmd %server% /zoneinfo %i &amp;#124; find /i "master"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find AdminSDHolder groups with GROUP_TYPE_SECURITY_ENABLED&lt;/b&gt;&lt;br /&gt;dsquery * domainroot -filter "(&amp;(objectCategory=Group)(objectClass=Group)(groupType:1.2.840.113556.1.4.803:=2147483648))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query an MIIS/IIFP database to find the management agent AD configuration&lt;/b&gt;&lt;br /&gt;select ma_name, private_configuration_xml from mms_management_agent&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check the MIIS/IIFP GALSync.xml file to find the management agent AD config&lt;/b&gt;&lt;br /&gt;Extensions\GALSync.xml&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query an MIIS/IIFP database to find the management agent AD containers to sync&lt;/b&gt;&lt;br /&gt;select filter_xml from mms_partition MMSP inner join mms_management_agent MMSA on MMSP.ma_id = MMSA.ma_id where ma_name = 'MA-NAME' and partition_name = 'DC=domainRoot'&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the IP address of a machine using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip set address name="Local Area Connection" source=static addr=192.168.0.10 mask=255.255.255.0 gateway=192.168.0.1 1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set local DNS client primary using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip add dns name="Local Area Connection" addr=192.168.0.10 index=1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set local DNS client secondary using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip add dns name="Local Area Connection" addr=192.168.0.11 index=2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set local WINS client primary using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip add wins name="Local Area Connection" addr="192.168.0.10" index=1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set local WINS client secondary using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip add wins name="Local Area Connection" addr="192.168.0.11" index=2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Modify service DACLs to allow service start stop (assumes query already exists)&lt;/b&gt;&lt;br /&gt;subinacl /service schedule /grant=builtin\users=TO&lt;br /&gt;&lt;br /&gt;&lt;b&gt;User cmdkey to add a stored credential when connecting to a remote server&lt;/b&gt;&lt;br /&gt;cmdkey /add:remote.domain.com /user:domain\user /pass:*&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the holders of the specified NT right / privilege&lt;/b&gt;&lt;br /&gt;showpriv SeProfileSingleProcessPrivilege&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the privileges the current user holds&lt;/b&gt;&lt;br /&gt;whoami /priv&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Delete the policy restriction to run adsiedit.msc&lt;/b&gt;&lt;br /&gt;reg delete "HKCU\Software\Policies\Microsoft\MMC\{1C5DACFA-16BA-11D2-81D0-0000F87A7AA3}"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Stop and then restart the ESX software iSCSI initiator&lt;/b&gt;&lt;br /&gt;/usr/sbin/esxcfg-swiscsi -d &amp;#124; /usr/sbin/esxcfg-swiscsi -e&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reset a computer account secure channel&lt;/b&gt;&lt;br /&gt;nltest /sc_reset:%domain%[\%dc%]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Reset the password for a computer account&lt;/b&gt;&lt;br /&gt;nltest /sc_change_pwd:%domain%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CSV directory export of one or more subcontainers of a container&lt;/b&gt;&lt;br /&gt;for /f %i in ('"dsquery ou OU=People,DC=domainRoot -scope onelevel -o rdn"') do csvde -f UserExport-%~i.csv -l givenName,sn,displayname,mail,targetAddress,proxyAddresses,mailnickname -d "OU=%~i,OU=People,DC=domainRoot" -r "(&amp;(objectClass=Contact)(objectCategory=Person))"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query VMFS volume information from the service console&lt;/b&gt;&lt;br /&gt;/usr/sbin/vmkfstools -P /vmfs/volumes/%GUID%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Change the volume label of a disk&lt;/b&gt;&lt;br /&gt;label %drive%: %newlabel%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find VMware CDP info from the service console&lt;/b&gt;&lt;br /&gt;esxcfg-info &amp;#124; grep -C 18 '\==+CDP Summary'&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add a non expiring enabled user account to the Active Directory&lt;/b&gt;&lt;br /&gt;dsadd user "CN=user,OU=Users,DC=test,DC=com" -pwd "password" -pwdneverExpires yes -disabled no -desc "Description"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Clear local DNS client settings using netsh&lt;/b&gt;&lt;br /&gt;netsh interface ip delete dns name="Local Area Connection" addr=ALL&lt;br /&gt;&lt;br /&gt;&lt;b&gt;From an ESX service console, scan for updates from a depot for UpdateManager&lt;/b&gt;&lt;br /&gt;/usr/sbin/esxupdate --HA --flushcache -d http://esx01/vci/hostupdates/hostupdate/esx/esx-3.5.0 scan&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check the VI35 Legato AAM HA agent&lt;/b&gt;&lt;br /&gt;cat /var/log/vmware/aam/aam_config_util_addnode.log&lt;br /&gt;&lt;br /&gt;&lt;b&gt;VMware VI35 HA Legato AAM, list the cluster manager&lt;/b&gt;&lt;br /&gt;/opt/vmware/aam/bin/ftcli -domain vmware -timeout 60 -cmd "listrules"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;VMware VI35 HA Legato AAM, list the cluster nodes&lt;/b&gt;&lt;br /&gt;/opt/vmware/aam/bin/ftcli -domain vmware -connect esx01 -port 8042 -timeout 60 -cmd "listnodes"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;VMware ESX VI35 List the software iSCSI targets&lt;/b&gt;&lt;br /&gt;/usr/sbin/vmkiscsi-tool -L -l vmhba32&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Mount a local volume inside a local folder&lt;/b&gt;&lt;br /&gt;mountvol c:\temp\mount1 \\?\Volume{f856ff87-70ae-11dc-8b8d-806d6172696f}\&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Remove a mount point&lt;/b&gt;&lt;br /&gt;mountvol C:\temp\mount1\ /d&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List junctions or mount points&lt;/b&gt;&lt;br /&gt;junction -s c:\temp&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the boot device for an ESX installation&lt;/b&gt;&lt;br /&gt;esxcfg-info -s &amp;#124; grep -A10 "Diagnostic Partition"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the boot device for an ESX installation&lt;/b&gt;&lt;br /&gt;esxcfg-info -s &amp;#124; egrep -A4 "Parallel SCSI Interface&amp;#124;Block SCSI Interface"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use vSphere RCLI to list an ESXi host filesystem&lt;/b&gt;&lt;br /&gt;vifs.pl --server %server% --username %username% --password %password% -D /host&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use vSphere RCLI to backup an ESXi host (esxcfg-cfgbackup.pl)&lt;/b&gt;&lt;br /&gt;vicfg-cfgbackup.pl --server %server% --username %username% --password %password% -s server.tgz&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ESX VI35 list the virtual machines and their disks for performance analysis&lt;/b&gt;&lt;br /&gt;/usr/lib/vmware/bin/vscsiStats -l&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ESX VI35 gather disk statistics and display the latency histogram in CSV&lt;/b&gt;&lt;br /&gt;/usr/lib/vmware/bin/vscsiStats -s; /usr/lib/vmware/bin/vscsiStats -x; /usr/lib/vmware/bin/vscsiStats -p latency -c;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get Windows Remote Management config on the local machine&lt;/b&gt;&lt;br /&gt;winrm get winrm/config&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Windows Remote Management quick configuration to create a listener&lt;/b&gt;&lt;br /&gt;winrm quickconfig&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Test Windows Remote Management listener on the local host&lt;/b&gt;&lt;br /&gt;winrm id&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a Windows Remote Management https listener on the local host&lt;/b&gt;&lt;br /&gt;winrm quickconfig -transport:https&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a self-signed certificate&lt;/b&gt;&lt;br /&gt;makecert" -r -pe -n -r 30/12/2039 -eku 1.3.6.1.5.5.7.3.1 -ss my-sr localMachine -sky Exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 c:\temp\test.cer&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the SNTP servers a comptuer is using for time synchronisation&lt;/b&gt;&lt;br /&gt;net time \\server /querysntp   &lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set the SNTP servers used for w32time synchronistaion&lt;/b&gt;&lt;br /&gt;net time \\server /setsntp:"192.168.0.10 192.168.0.11"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Convert time from 100 nanosecond intervals since epoch 01/01/1601&lt;/b&gt;&lt;br /&gt;w32tm /ntte 127076450620627215&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Install the w32time Windows Time service&lt;/b&gt;&lt;br /&gt;w32tm /register&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Enable NTP Server for a w32time service&lt;/b&gt;&lt;br /&gt;reg add \\server\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer /v Enabled /t reg_dword /d 0x1 /f&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the error description given a win32 error number&lt;/b&gt;&lt;br /&gt;net helpmsg 2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Delete the policy value controlling whether recently run programs are recorded&lt;/b&gt;&lt;br /&gt;reg delete HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer /v NoRecentDocsHistory&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set registry permissions (subinacl 5.2.3790.1180 or later)&lt;/b&gt;&lt;br /&gt;subinacl /keyreg "\\server\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /grant=domain\group=F&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set service DACLs (Q : Query SC, S: status, I: interrogate, T: Start, O: Stop)&lt;/b&gt;&lt;br /&gt;subinacl /service \\server\schedule /grant=domain\group=TOQSI&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Rename a LAN interface name (ncpa.cpl)&lt;/b&gt;&lt;br /&gt;netsh interface set int name="Local Area Connection 2" newname="Local Area Connection"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find all network devices&lt;/b&gt;&lt;br /&gt;devcon findall =net&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find all network adapters for the Net class&lt;/b&gt;&lt;br /&gt;devcon listclass net&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Remove an old VMware VI3 PCNET Flexible/VLance/VMXNET adapter instance (@)&lt;/b&gt;&lt;br /&gt;devcon remove "@PCI\VEN_1022&amp;DEV_2000&amp;SUBSYS_20001022&amp;REV_10\3&amp;61AAA01&amp;0&amp;88"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find where a file is in the path&lt;/b&gt;&lt;br /&gt;for %i in (calc.exe) do echo %~$PATH:i&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the physical disk sector size&lt;/b&gt;&lt;br /&gt;wmic path win32_diskdrive get BytesPerSector&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the current amount of memory used by the file system virtual cache&lt;/b&gt;&lt;br /&gt;wmic path Win32_PerfFormattedData_PerfOS_Memory get SystemCacheResidentBytes&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Use robocopy in backup mode to take a copy of folder-level permissions&lt;/b&gt;&lt;br /&gt;Robocopy \\server\source c:\temp\copy zxcvsadfqwer /E /B /COPYALL /R:1 /W:1&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find remote shares and paths using WMI&lt;/b&gt;&lt;br /&gt;wmic /node:%server% path win32_share get Name,Path,Description&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find total memory, free memory and used paging file&lt;/b&gt;&lt;br /&gt;wmic /node:%server% path Win32_OperatingSystem Get FreePhysicalMemory,FreeSpaceInPagingFiles,TotalVirtualMemorySize,TotalVisibleMemorySize&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Search a remote computer's registry for a string&lt;/b&gt;&lt;br /&gt;regfind -m \\%server% -y -b -n search_string&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Set a computer to use a specified number of available processors&lt;/b&gt;&lt;br /&gt;modify boot.ini, use the /NUMPROC=x switch or /ONECPU switch&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Check the Exchange ESE buffer cache size&lt;/b&gt;&lt;br /&gt;dsquery * "CN=InformationStore,CN=exchserver01,CN=Servers,CN=AdminGroup01,CN=Administrative Groups,CN=organisation,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=domainRoot" -attr msExchESEParamCacheSizeMax -scope base&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query the start of authority record for a DNS zone&lt;/b&gt;&lt;br /&gt;dnscmd %server% /enumrecords %fqdn% @ /type SOA&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-40197023012568785?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=40197023012568785' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/40197023012568785'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/40197023012568785'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/09/more-useful-command-lines.html' title='More useful command-lines'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8590985386563486408</id><published>2009-08-11T22:24:00.000+10:00</published><updated>2009-08-11T22:24:44.850+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>VMware PowerCLI - Reconfigure cluster options</title><content type='html'>The following script contains a simple example of how to modify the configuration of a cluster – in this case to add two advanced options to the HA settings.  This uses the new ClusterConfigSpecEx object, which can be used with the more generic function to reconfigure a resource – ReconfigureComputeResource().&lt;br /&gt;&lt;br /&gt;The options set in this example are the das.allowNetworkX options, configuring HA to set specific management networks/service consoles that are used for HA communication and heartbeats.&lt;br /&gt;&lt;br /&gt;Consider the following scenario for a reason why you might want to use these options:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Software iSCSI with ESX 3.x – using the service console for authentication, meaning you need a service console on your iSCSI network (or routes between your corporate network and iSCSI).  The standard result is that HA could be used across this interface.&lt;/li&gt;&lt;li&gt;You are progressing with an upgrade to ESXi 4.0, still using software iSCSI, which is improved to remove the need for a management interface on your iSCSI network&lt;/li&gt;&lt;li&gt;You put an ESX 3.5 and ESXi 4.0 host in the same cluster, HA no longer works because your iSCSI service console on ESX 3.5 can’t talk to your ESXi 4.0 host.&lt;/li&gt;&lt;li&gt;Adding the two options above (with names changed appropriately) would force HA to use the service console on ESX 3.5 and the equivalent management network on ESXi 4.0, ignoring the iSCSI service console on 3.5 - resolving HA issues.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;# http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.ComputeResource.html#reconfigureEx&lt;br /&gt;# http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.cluster.DasConfigInfo.html#field_detail&lt;br /&gt;&lt;br /&gt;param (&lt;br /&gt;    $vcServerName = ""&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;$viServer = Connect-VIServer -server $vcServerName&lt;br /&gt;&lt;br /&gt;$optionValue = New-Object Vmware.Vim.OptionValue&lt;br /&gt;$optionValue.Key = "das.allowNetwork0"&lt;br /&gt;$optionValue.Value = "Service Console"&lt;br /&gt;&lt;br /&gt;$optionValue2 = New-Object Vmware.Vim.OptionValue&lt;br /&gt;$optionValue2.Key = "das.allowNetwork1"&lt;br /&gt;$optionValue2.Value = "Management Network"&lt;br /&gt;&lt;br /&gt;[Vmware.Vim.OptionValue[]]$optionValues = $optionvalue, $optionValue2  # Create the array of the two new option values&lt;br /&gt;&lt;br /&gt;$cluster = get-cluster -Name 'Cluster01'     # Get the cluster&lt;br /&gt;$clusterview = get-view $cluster.Id      # Get the SDK object from the PowerCli object MO&lt;br /&gt;&lt;br /&gt;$spec = New-Object Vmware.Vim.ClusterConfigSpecEx&lt;br /&gt;$spec.dasConfig = New-Object Vmware.Vim.ClusterDasConfigInfo   # New VMware HA config&lt;br /&gt;&lt;br /&gt;$spec.dasConfig.option = $optionValues      # Add the array of optionValues&lt;br /&gt;$clusterview.ReconfigureComputeResource($spec, $true)    # Modify the configuration. When configuring clusters, can be a ClusterConfigSpecEx object&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# Check the settings were saved&lt;br /&gt;&lt;br /&gt;$cluster = get-cluster -Name 'Cluster01'     # Get the cluster&lt;br /&gt;$clusterview = get-view $cluster.Id      # Get the SDK object from the PowerCli object MO&lt;br /&gt;&lt;br /&gt;$clusterview.Configuration.dasConfig.Option | format-list   # Retrieve the advanced options&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8590985386563486408?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8590985386563486408' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8590985386563486408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8590985386563486408'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/08/vmware-powercli-reconfigure-cluster.html' title='VMware PowerCLI - Reconfigure cluster options'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-105611671409632668</id><published>2009-08-11T22:06:00.000+10:00</published><updated>2009-08-11T22:06:21.780+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>VMware PowerCLI - Backup ESXi 4.0 firmware</title><content type='html'>The following script contains a simple function to use the VMware vSphere PowerCLI to connect to a vCenter and/or ESXi 4.0 host and backup the 'firmware' - the configuration of the ESX host.  I don’t think this functionality is exposed directly through the PowerCLI, so a call to the very useful Get-View function is used to get the VI SDK object to call the appropriate method.  &lt;br /&gt;&lt;br /&gt;From what I can tell all this command does is generate a config dump on the server and return the HTTP URL to access the file download, which I’m then using the .Net web client object to download the file and store as the filename returned with a unique date suffix.&lt;br /&gt;&lt;br /&gt;This certainly isn’t original, all I did was look at the vicfg-backup.pl perl RCLI script and (badly) translate to PowerCLI from there.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;#&lt;br /&gt;# Description:&lt;br /&gt;#  Backup the firmware configuration on an ESXi 4.0 host&lt;br /&gt;#&lt;br /&gt;# Limitations:&lt;br /&gt;#  -&lt;br /&gt;#&lt;br /&gt;# Assumptions, this script works on the assumption that:&lt;br /&gt;#  The caller provides credentials with permissions to connect to the specified host&lt;br /&gt;#&lt;br /&gt;# Arguments:&lt;br /&gt;#  esxServer, the ESX host to connect to, eg. esx01&lt;br /&gt;#  vcServerName, The vCenter Server to connect to, eg vc01&lt;br /&gt;#  outputDir, The directory to write the backup file to, defaults to %temp%&lt;br /&gt;#  username, The username to use when connecting to the vCenter server (if specified), defaults to %username%&lt;br /&gt;#  password, The password to use for the connection to vCenter, secure string prompt by default&lt;br /&gt;#&lt;br /&gt;# Usage:&lt;br /&gt;#  PowerShell . .\BackupFirmware.ps1 -esxServer 'esx01'&lt;br /&gt;#  PowerShell . .\BackupFirmware.ps1 -esxServer 'esx01' -vcServer vc01 -u domain\username&lt;br /&gt;#&lt;br /&gt;# References:&lt;br /&gt;#  http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.FirmwareSystem.html&lt;br /&gt;#&lt;br /&gt;# Changes:&lt;br /&gt;#  04/07/2009, Wayne Martin, initial version&lt;br /&gt;&lt;br /&gt;#$ErrorActionPreference = "Continue"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;param (&lt;br /&gt;    $esxServer = "",&lt;br /&gt;    $vcServerName = "",&lt;br /&gt;&lt;br /&gt;    $outputDir = $env:Temp,&lt;br /&gt;&lt;br /&gt;    $username = $env:username,&lt;br /&gt;    $password = ""&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;if ($password -eq "" -and !($pass)) {&lt;br /&gt;    write-output "No password specified from the command-line"&lt;br /&gt;    $pass = Read-Host "Password?" -assecurestring&lt;br /&gt;    $credential = new-object System.Management.Automation.PSCredential($username,$pass)    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if ($esxServer -eq "" -OR ($vcServerName -eq "" -and $esxServer -eq "")) {&lt;br /&gt;    Write-Output "Please specify either a standalone host, or a host and a cluster"&lt;br /&gt;    Exit 2&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$viServer = $null&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function BackupConfiguration([string] $vcServerName, [string] $esxServer, [string] $outputDir){&lt;br /&gt;    $hostSystem = get-view -ViewType HostSystem -Filter @{"Name" = $esxServer}    # Find the .Net view of the specified host&lt;br /&gt;&lt;br /&gt;    $hostConfigManager = $hostSystem.get_ConfigManager()      # Get the config manager&lt;br /&gt;    $hostfirmwareSystem = $hostConfigManager.get_firmwareSystem()     # Find the MOR of the host firmware system&lt;br /&gt;&lt;br /&gt;    $hostfirmware = Get-View $hostfirmwareSystem        # Get the VMware.Vim.HostFirmwareSystem object from the MOR&lt;br /&gt;&lt;br /&gt;    $backupDownload = $hostfirmware.BackupFirmwareConfiguration()     # Call the backup method to generate the config bundle&lt;br /&gt;&lt;br /&gt;    $backupDownload = $backupDownload.Replace("*", $esxServer)      # Replace '*' with the server name&lt;br /&gt;&lt;br /&gt;    Write-Output "Backup saved to $backupDownload on the ESX host"&lt;br /&gt;    $fileName = $backupDownload.SubString($backupDownload.LastIndexOf("/")+1)    # Extract the filename to reuse&lt;br /&gt;    $fileType = $fileName.SubString($fileName.LastIndexOf("."))      # Find the extension (.tgz in this case)&lt;br /&gt;&lt;br /&gt;    $Now = [DateTime]::Now.ToString("yyyyMMddTHHmmss")          # Unique identifier for the filename&lt;br /&gt;    $file = $fileName.SubString(0, $fileName.Length - $fileType.Length)     # File name without extension&lt;br /&gt;    $outputFile = $outputDir + "\" + $file + "_" + $Now + $fileType     # Construct the full filename path\bundle_date.tgz&lt;br /&gt;&lt;br /&gt;    $wc = new-object system.net.WebClient        # use the .Net web client&lt;br /&gt;    $wc.DownloadFile($backupDownload, $outputFile)       # Download the file from the URL returned&lt;br /&gt;&lt;br /&gt;    if (test-path -path $outputFile) {         # Does the output file exist?&lt;br /&gt;        Write-Output "$outputFile downloaded"&lt;br /&gt;    } else {&lt;br /&gt;        Write-Output "Error: $outputFile was not downloaded from $backupDownload"&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if ($vcServerName -ne "") {&lt;br /&gt;    $viServer = Connect-VIServer -server $vcServerName -Credential $credential&lt;br /&gt;} elseif ($esxServer -ne "") {&lt;br /&gt;    $esxServer = Connect-VIServer -server $esxServer       # connect to VC&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$results = ""&lt;br /&gt;$results = BackupConfiguration $vcServerName $esxServer $outputDir&lt;br /&gt;&lt;br /&gt;$results&lt;br /&gt;&lt;br /&gt;if ($vcServerName -ne "") {&lt;br /&gt;    Disconnect-VIServer -confirm:$false&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-105611671409632668?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=105611671409632668' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/105611671409632668'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/105611671409632668'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/08/vmware-powercli-backup-esxi-40-firmware.html' title='VMware PowerCLI - Backup ESXi 4.0 firmware'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7284743803067399216</id><published>2009-08-06T19:56:00.000+10:00</published><updated>2009-08-06T19:56:15.066+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>VMware vSphere PowerCLI commands</title><content type='html'>The commands below are PowerCLI commands used to automate VMware ESX and VirtualCenter at the command prompt.  Most of these commands were built on 3.5 with vSphere PowerCLI, and the majority have been tested against ESXi 4.0 and vCenter 4.0 infrastructure.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at a PowerCLI command prompt, and most commands assume you already have a connection to the target, be it vCenter or ESX.&lt;br /&gt;&lt;br /&gt;Note that most of these commands use OBN - Object By Name - instead of using the get* command to get the object.  This is supported with all but a few of the commands I've come across.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the vSphere PowerCLI commands&lt;/b&gt;&lt;br /&gt;Get-VICommand&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Connect to a ESX or VirtualCenter instance&lt;/b&gt;&lt;br /&gt;connect-viserver -server %server%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the currently available datastores&lt;/b&gt;&lt;br /&gt;Get-Datastore &amp;#124; sort&lt;br /&gt;&lt;br /&gt;&lt;b&gt;List the currently available datastores filtered and sorted&lt;/b&gt;&lt;br /&gt;Get-Datastore &amp;#124; where {$_.Name -like '*pr*'} &amp;#124; sort&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the VMs attached to one or more datastores&lt;/b&gt;&lt;br /&gt;foreach ($prodDatastore in $prodDatastores) { write-output $prodDatastore.Name; get-vm -datastore $proddatastore; write-output ''}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get a Virtual Machine&lt;/b&gt;&lt;br /&gt;$vm = get-vm -name '%vm%'&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get the virtual harddisk for the specified VMs&lt;/b&gt;&lt;br /&gt;Get-HardDisk -vm $vm&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Move a virtual machine to another container&lt;/b&gt;&lt;br /&gt;Move-VM -Destination $prodApps -VM $vm&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update the VM description for a list of CSV entries&lt;/b&gt;&lt;br /&gt;foreach ($virtualServer in $virtualservers) {$arr = $virtualServer.split(","); $desc = $arr[1]; $vmName = $arr[0]; write-output $vmName; $desc; $vm = get-vm -name $vmName; Set-VM -VM $vm -description $desc}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for a list of VMs and output in ANSI format&lt;/b&gt;&lt;br /&gt;get-vm &amp;#124; sort-object &amp;#124; format-table -property Name &amp;#124; out-file -encoding ASCII -filepath c:\temp\vms_20090625.txt&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find VMware machine performance statistics&lt;/b&gt;&lt;br /&gt; get-stat -entity $vm -disk -start 01/01/2009 -finish ([DateTime]::Now.ToString("dd/MM/yyyy"))&lt;br /&gt;&lt;br /&gt;&lt;b&gt;For a group of VMs, report performance statistics and save to file&lt;/b&gt;&lt;br /&gt;foreach ($vm in $devVMs) {get-stat -entity $vm -disk -start 01/01/2009 -finish ([DateTime]::Now.ToString("dd/MM/yyyy")) &amp;#124; out-file -filepath ("c:\temp\" + $vm.Name + "DiskPerformance.txt")}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find VM datastore disk usage&lt;/b&gt;&lt;br /&gt;$devVMs = get-vm -name '*dv*'; foreach ($vm in $devvms) {$vm.harddisks}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find VM datastore disk usage&lt;/b&gt;&lt;br /&gt;$testVMs = Get-VM -Location (get-folder -name "Test") ;foreach ($vm in $testVMs) {$vm.harddisks &amp;#124; format-table -hideTableHeaders -wrap -autosize &amp;#124; findstr /i /c:per}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find SCSI devices attached to an ESX server&lt;/b&gt;&lt;br /&gt;get-scsilun -vmhost (Get-VMHost -Location "cluster")[0]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Rescan HBAs on an ESX server&lt;/b&gt;&lt;br /&gt;get-VMHostStorage -VMHost (Get-VMHost -Location "cluster")[0] -RescanAllHba&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Storage vMotion a virtual machine to a new datastore&lt;/b&gt;&lt;br /&gt;Move-VM -vm "vmName" -datastore "NewDatastore"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Storage vMotion a group of machines from a CSV input file&lt;/b&gt;&lt;br /&gt;$servers = get-content -path inputfile.txt; foreach ($server in $servers) {move-vm -vm $server.split(",")[0] -datastore $server.split(",")[1]}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Remove a snapshot and child snapshots, reporting how long the operation took&lt;/b&gt;&lt;br /&gt;measure-command -expression {remove-snapshot -snapshot $snapshots[0] -removechildren}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find datastore space, usage and number of VMs per datastore&lt;/b&gt;&lt;br /&gt;$datastores = get-datastore &amp;#124; sort-object; write-output "Name,Size,Used,Free,% Used,#VMs"; foreach ($datastore in $datastores) { write-output ($datastore.Name + "," + [math]::round($datastore.CapacityMB/1024) + "," + [math]::round(($datastore.CapacityMB/1024)-($datastore.FreeSpaceMB/1024)) + "," + [math]::round($datastore.FreeSpaceMB/1024) + "," + [math]::round(((($datastore.CapacityMB/1024) - ($datastore.FreeSpaceMB/1024)) / ($datastore.CapacityMB/1024)) * 100) + "," + (get-vm -datastore $datastore).count)}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;From a set of VMs, find which have snapshots&lt;/b&gt;&lt;br /&gt;foreach ($testvm in $testvms) {if (get-snapshot -vm $testvm){write-output $testvm.Name}}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the size of the first hard disk in each VM&lt;/b&gt;&lt;br /&gt;foreach ($vm in $vms) {$vm.harddisks[0] &amp;#124; format-table -hideTableHeaders -wrap -autosize &amp;#124; findstr /i /c:per }&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find disk information for VMs in the specified datastore&lt;/b&gt;&lt;br /&gt; $VMs = Get-VM ;foreach ($vm in $VMs) {$vm.harddisks &amp;#124; where {$_.FileName -like '*clusterpr*'} &amp;#124; format-table -hideTableHeaders -wrap -autosize &amp;#124; findstr /i /c:per}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find VMs in the specified datastore&lt;/b&gt;&lt;br /&gt;$VMs = Get-VM &amp;#124; where {$_.harddisks[0].FileName -like '*clusterpr*'}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get VM guest information, including virtual OS&lt;/b&gt;&lt;br /&gt;get-vm &amp;#124; get-vmguest &amp;#124; format-table -wrap -autosize&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find virtual machines and their description/notes&lt;/b&gt;&lt;br /&gt;$vms = get-vm ; $vms &amp;#124; format-table -wrap -autosize -property Name,Description&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create an associative array containing VM names and descriptions&lt;/b&gt;&lt;br /&gt;$vmdesc = @{}; foreach ($vm in $vms) {$vmdesc.add($vm.Name, $vm.Description)}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Migrate a virtual machine to another host in a VMware ESX cluster&lt;/b&gt;&lt;br /&gt;move-vm -vm %vmName% -destination %hostname%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the host a VM is currently located on&lt;/b&gt;&lt;br /&gt;get-vmhost -vm %vnName%&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Add a new harddisk to a virtual machine&lt;/b&gt;&lt;br /&gt;New-HardDisk -vm %vmName% -CapacityKB 20971520&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Retrieve details on the resource pools from the currently connected datacenter&lt;/b&gt;&lt;br /&gt;Get-ResourcePool &amp;#124; format-table -wrap -autosize -property Name,Id,CpuExpandableReservation,CpuLimitMHz,CpuReservationMHz,CpuSharesLevel,CustomFields,MemExpandableReservation,MemLimitMB,MemReservationMB,MemSharesLevel,Name,NumCpuShares,NumMemShares&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find virtual machines and if they have a CD-ROM&lt;/b&gt;&lt;br /&gt;get-vm &amp;#124; format-table -wrap -autosize -property Name,CDDrives&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find the last 100 events that aren't alarm related&lt;/b&gt;&lt;br /&gt;$events = Get-VIEvent -MaxSamples 100 &amp;#124; where {$_.fullFormattedMessage -notmatch "Alarm*"}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find all events for machine deployments from templates&lt;/b&gt;&lt;br /&gt;$events = Get-VIEvent &amp;#124; where {$_.fullFormattedMessage -match "Deploying (.*) on host (.*) in (.*) from template (.*)"}&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a resource pool with high CPU and memory shares&lt;/b&gt;&lt;br /&gt;New-ResourcePool -location (get-cluster -name 'cluster') -Name ResPool1 -CpuSharesLevel [VMware.VimAutomation.Types.SharesLevel]::High -MemSharesLevel [VMware.VimAutomation.Types.SharesLevel]::High&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create a folder from the root of the tree&lt;/b&gt;&lt;br /&gt;New-Folder -Name Workstations -location (get-folder -name 'vm')&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Move one or more VMs to a resource pool (or other destination)&lt;/b&gt;&lt;br /&gt;$vms = get-vm -name vmNames*; move-vm -vm $vms -destination (Get-ResourcePool -name 'ResPool1')&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get an OS customization specification, and list the properties in wide format&lt;/b&gt;&lt;br /&gt;Get-OSCustomizationSpec -name "SpecName" &amp;#124; format-list&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Take a snapshot of a virtual machine&lt;/b&gt;&lt;br /&gt;New-Snapshot -Name "Snapshot 01" -description "Snapshot description" -vm vmName -Quiesce:$true&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Convert a virtual machine to a template&lt;/b&gt;&lt;br /&gt;$vmView = get-vm -name vm01 &amp;#124; Get-View; $vmView.MarkAsTemplate()&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Find Datastore usage (custom written function)&lt;/b&gt;&lt;br /&gt;get-datastoreusage&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Get an ESX log bundle using PowerCLI&lt;/b&gt;&lt;br /&gt;Get-Log -VMHost esxhostname -Bundle -DestinationPath c:\temp&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for snapshots&lt;/b&gt;&lt;br /&gt;Get-VM &amp;#124; Get-Snapshot &amp;#124; export-csv -path c:\temp\VMsnapshots.csv&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Query for snapshot information&lt;/b&gt;&lt;br /&gt;Get-VM &amp;#124; Get-Snapshot &amp;#124; foreach-object {$out=  $_.VM.Name + "," + $_.Name + "," + $_.Description + "," + $_.PowerState; $out}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7284743803067399216?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7284743803067399216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7284743803067399216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7284743803067399216'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/08/vmware-vsphere-powercli-commands.html' title='VMware vSphere PowerCLI commands'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-5998027467741118666</id><published>2009-08-06T19:38:00.002+10:00</published><updated>2009-08-06T19:39:42.014+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workstation'/><category scheme='http://www.blogger.com/atom/ns#' term='Active Directory'/><title type='text'>Resetting Computer Account Passwords</title><content type='html'>I was trying to tell from a workstation point of view when the computer account password was last set.  I'm sure this information is stored locally somewhere, but in the end it was easier to query the AD and find when the password for the computer account was last set.&lt;br /&gt;&lt;br /&gt;This is used for Virtual Machine templates - we use nltest to reset the computer account password, such that we can maintain a single template image and turn it on periodically for updates without having to rejoin to the domain because of mismatched computer accounts.&lt;br /&gt;&lt;br /&gt;Forcefully reset the computer account password:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;nltest /SC_CHANGE_PWD:%domain%&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Query the workstation in the domain and find when the password was last set - returns the number of 100 nanosecond intervals since 01/01/1601.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;dsquery computer -name ws01&lt;br /&gt;dsquery * "CN=ws01,OU=Computers,DC=domain,DC=com" -attr pwdlastset&lt;br /&gt;pwdlastset&lt;br /&gt;128934012123005000&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Use PowerShell to convert the number to a human readable date format:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;powershell [datetime]::FromFileTime(128934012123005000)&lt;br /&gt;&lt;br /&gt;Thursday, 30 July 2009 2:20:12 PM&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Use w32tm to convert the number to a human readable date format:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;w32tm /ntte 128934012123005000&lt;br /&gt;&lt;br /&gt;149229 04:20:12.3005000 - 30/07/2009 2:20:12 PM&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Use VBScript to convert the number to a human readable date format:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;cscript ConvertFileTime.vbs 128934012123005000&lt;br /&gt;&lt;br /&gt;30/07/2009 2:20:12 PM&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;' ConvertFileTime.vbs&lt;br /&gt;' VBScript doesn't support 64-bit integers, so it can't handle the number of 100 nanosecond intervals since 01/01/1601&lt;br /&gt;' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnclinic/html/scripting09102002.asp&lt;br /&gt;&lt;br /&gt;' Either use ADSI provider and the IADs/IADsLargeInteger object&lt;br /&gt;' LargeIntValue = objLargeInt.HighPart * 2^32 + objLargeInt.LowPart&lt;br /&gt;&lt;br /&gt;' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/iadslargeinteger.asp'&lt;br /&gt;' Or WMI, which handles the conversion between 64-bit datetime structure / UTC / and VB var datetime&lt;br /&gt;&lt;br /&gt;If Wscript.Arguments.UnNamed.Count &gt; 0 Then &lt;br /&gt;        strDateTime = Wscript.Arguments.UnNamed(0)&lt;br /&gt;        Set objDateTime = CreateObject("WbemScripting.SWbemDateTime")&lt;br /&gt;        If IsDate(strDateTime) Then&lt;br /&gt;                Call objDateTime.SetVarDate(strDateTime, False)&lt;br /&gt;                wscript.echo objDateTime.GetFileTime&lt;br /&gt;        Else&lt;br /&gt;                Call objDateTime.SetFileTime(strDateTime, False)&lt;br /&gt;                wscript.echo objDateTime.GetVarDate&lt;br /&gt;        End If&lt;br /&gt;        intReturn = 0&lt;br /&gt;Else&lt;br /&gt;        WScript.Echo "Specify a filetime or a date to convert, eg 127076450620627215, or ""11/04/2006 11:17:10 AM"""&lt;br /&gt;        intReturn = 2&lt;br /&gt;End If&lt;br /&gt;WScript.Quit(intReturn)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-5998027467741118666?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=5998027467741118666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5998027467741118666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5998027467741118666'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/08/resetting-computer-account-passwords.html' title='Resetting Computer Account Passwords'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4463403549876742731</id><published>2009-07-27T19:00:00.000+10:00</published><updated>2009-07-27T19:00:36.673+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>PowerCli Relocate VM storage with VI35 / VI4</title><content type='html'>This post provides a script to help with storage vMotion – migrating a VMware virtual machine from one VMFS datastore to another with no downtime.  It’s a great tool, but in VI35 at least it’s not exposed through the GUI or VC scheduled tasks, so I’ve written a script to perform a few checks and allow for very simplistic 'scheduling' (delay).&lt;br /&gt;&lt;br /&gt;I’ve only tested this with VI3.5 and PowerCLI 1.0, but I have no reason to think this wouldn’t with with vSphere vCenter and VI 4.0 hosts.&lt;br /&gt;&lt;br /&gt;There are a few caveats with storage vMotion (in VC 2.5/ESX 3.5) at least, you can’t:&lt;br /&gt;- Move the storage of a VM that has a snapshot if the VM is powered on&lt;br /&gt;- Move the storage of a VM that has a snapshot (in any power state) if the VM has disks in a different location than the config file. &lt;br /&gt;&lt;br /&gt;Based on these caveats, if instructed the script will suspend a VM with snapshots in order to move the storage, then power the VM back on.  Use this with caution, as this may cause an outage of your VMs.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;#&lt;br /&gt;# Description:&lt;br /&gt;#   Relocate a virtual machine from one datastore to another.&lt;br /&gt;#&lt;br /&gt;# Limitations:&lt;br /&gt;#  -&lt;br /&gt;#&lt;br /&gt;# Assumptions, this script works on the assumption that:&lt;br /&gt;#   The caller provides credentials with permissions to perform the operations&lt;br /&gt;#&lt;br /&gt;# Arguments:&lt;br /&gt;#  vmName, lowecase short name for the virtual machine, eg pibutepr03&lt;br /&gt;#  dataStoreName, the new datastore to migrate the VM to&lt;br /&gt;#  suspend, Whether or not to suspend a VM and move if the VM has snapshots (which prevent live storage vMotion vi VI35)&lt;br /&gt;#  username, The username to connect with, default to the current username environment variable&lt;br /&gt;#  password, The Password to use for the connection, not specifying a password will result in a prompt to enter a secure string&lt;br /&gt;#  delay, The optional number of seconds to delay before starting the operation&lt;br /&gt;#&lt;br /&gt;#&lt;br /&gt;# Usage:&lt;br /&gt;#   PowerShell . .\RelocateVM.ps1 -vmName "vm01" -datastore 'ds02'&lt;br /&gt;#   PowerShell . .\RelocateVM.ps1 -vmName "vm01" -datastore 'ds02' -suspend yes -username domain\user&lt;br /&gt;#&lt;br /&gt;# Changes:&lt;br /&gt;#  07/04/2009, Wayne Martin, Initial version&lt;br /&gt;#&lt;br /&gt;&lt;br /&gt;param (&lt;br /&gt;&lt;br /&gt;    $vmName = "",&lt;br /&gt;    $dataStoreName = "",&lt;br /&gt;    $suspendIfRequired = $false,&lt;br /&gt;    $username = $env:username,&lt;br /&gt;    $password = "",&lt;br /&gt;    $delay = 0&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$ErrorActionPreference = "Continue"&lt;br /&gt;&lt;br /&gt; $invalidArgs = $false&lt;br /&gt;if ($dataStoreName -eq "") { write-output "Please specify the datastore target for the VM, eg. ds02"; $invalidArgs = $true}&lt;br /&gt;if ($vmName -eq "") { write-output "Please specify the virtual machine to move, eg vm01"; $invalidArgs = $true}&lt;br /&gt;if ($account -eq "") { write-output "Please specify a user account to connect with, eg domain\user"; $invalidArgs = $true}&lt;br /&gt;&lt;br /&gt;if ($invalidArgs) { write-output "Invalid Arguments, terminating"; exit}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Write-Output "Moving VM '$vmName' to the '$dataStoreName' datastore"&lt;br /&gt;&lt;br /&gt;if ($delay -gt 0) {&lt;br /&gt;    $hours = $delay / 60 /60&lt;br /&gt;    Write-Output "Delaying $delay seconds before beginning ($hours hours)"&lt;br /&gt;    Sleep -seconds $delay&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if ($suspendIfRequired) {&lt;br /&gt;    Write-Output "The virtual machine will be suspended if snapshots are preventing storage vMotion"&lt;br /&gt;} else {&lt;br /&gt;    Write-Output "If the virtual machine has snapshots and is powered on the storage vMotion will not work"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if ($password -eq "" -and !($pass)) {&lt;br /&gt;    write-output "No password specified from the command-line"&lt;br /&gt;    $pass = Read-Host "Password?" -assecurestring&lt;br /&gt;}&lt;br /&gt;$credential = new-object System.Management.Automation.PSCredential($username,$pass)    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$viServer = $null&lt;br /&gt;$suspend = $false&lt;br /&gt;$poweredOn = ""&lt;br /&gt;$snapshot = $null&lt;br /&gt;$hasSnapshot = $null&lt;br /&gt;&lt;br /&gt;$viServer = Connect-VIServer -server $vcServerName -Credential $credential&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if ($viServer) {&lt;br /&gt;    Write-Output (Get-Date -format "dd/MM/yyyy HH:mm:ss")&lt;br /&gt;    write-output ("Connected to server " + $viServer.Name + " on port " + $viServer.Port)&lt;br /&gt;&lt;br /&gt;    $vm = get-vm -name $vmName&lt;br /&gt;    if ($vm -and $vm -isnot [object[]]) {&lt;br /&gt;        Write-Output ("Found " + $vm.Name)&lt;br /&gt;&lt;br /&gt;        $hardDisks = $vm.hardDisks&lt;br /&gt;        $vmSize = 0&lt;br /&gt;        $vmSizeMB = 0&lt;br /&gt;        foreach ($harddisk in $vm.hardDisks) {&lt;br /&gt;            $vmSize += $hardDisk.CapacityKB&lt;br /&gt;        }&lt;br /&gt;        $vmSizeMB = $vmSize /1024&lt;br /&gt;&lt;br /&gt;        $datastore = get-datastore -name $dataStoreName&lt;br /&gt;        if ($datastore) {&lt;br /&gt;            $freeSpace = $datastore.FreeSpaceMB&lt;br /&gt;        &lt;br /&gt;            if ($freeSpace -gt $vmSizeMB)&lt;br /&gt;            {&lt;br /&gt;                Write-Output "The datastore $datastoreName has $freeSpace MB available, the VM has disks totalling $vmSizeMB MB"&lt;br /&gt;            &lt;br /&gt;                switch ($vm.PowerState)&lt;br /&gt;                {&lt;br /&gt;                    ([VMware.VimAutomation.Types.PowerState]::PoweredOn)&lt;br /&gt;                    {&lt;br /&gt;                        Write-Output "The virtual machine is currently powered on"&lt;br /&gt;                        $poweredOn = $true&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                    ([VMware.VimAutomation.Types.PowerState]::PoweredOff)&lt;br /&gt;                    {&lt;br /&gt;                        Write-Output "The virtual machine is currently powered off"&lt;br /&gt;                    }&lt;br /&gt;&lt;br /&gt;                    ([VMware.VimAutomation.Types.PowerState]::Suspended)&lt;br /&gt;                    {&lt;br /&gt;                        Write-Output "The virtual machine is currently suspended"&lt;br /&gt;                    }&lt;br /&gt;            &lt;br /&gt;                    default&lt;br /&gt;                    {&lt;br /&gt;                        write-output "Virtual machine power state unknown"&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                [object[]]$snapshot = get-snapshot -vm $vm&lt;br /&gt;                if ($snapshot) &lt;br /&gt;                {&lt;br /&gt;                    $hasSnapshot = $true&lt;br /&gt;                    $numSnapshots = $snapshot.Count&lt;br /&gt;                    Write-Output "$vmName currently has $numSnapshots snapshot(s)"&lt;br /&gt;                    if ($poweredOn) {&lt;br /&gt;                        if ($suspendIfRequired) {&lt;br /&gt;                            Write-Output "$vmName is powered on and has a snapshot, and will be suspended during the move"&lt;br /&gt;                            $suspend = $true&lt;br /&gt;                        } else {&lt;br /&gt;                            Write-Output "Error: $vmName is powered on and has a snapshot, but will not be suspended, process aborted"&lt;br /&gt;                            $suspend = $false&lt;br /&gt;                            exit 2&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                } else {&lt;br /&gt;                    $suspend = $false&lt;br /&gt;                    $hasSnapshot = False&lt;br /&gt;                    Write-Output "No snapshots currently found for $vmName"&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                if ($suspend) {&lt;br /&gt;                    Write-Output "Suspending $vmName"&lt;br /&gt;                    Suspend-VM -vm $vm -confirm:$false&lt;br /&gt;                }&lt;br /&gt;&lt;br /&gt;                Write-Output "Moving $vmName to $datastoreName"&lt;br /&gt;                Move-VM -vm $vmName -datastore $datastoreName&lt;br /&gt;&lt;br /&gt;                if ($suspend) {&lt;br /&gt;                    Write-Output "Bringing $vmName out of suspension"&lt;br /&gt;                    Start-VM -vm $vm -confirm:$false&lt;br /&gt;                }&lt;br /&gt;                Write-Output "$vmName migrated to $datastoreName"&lt;br /&gt;&lt;br /&gt;            } else {&lt;br /&gt;                Write-Output "The datastore only has $freeSpace MB available, but the VM has disks totalling $vmSizeMB MB"&lt;br /&gt;            }&lt;br /&gt;        } else {&lt;br /&gt;            Write-Output "Error: datastore $datastoreName not found"&lt;br /&gt;        }&lt;br /&gt;    } else {&lt;br /&gt;        if ($vm -is [object[]])&lt;br /&gt;        {&lt;br /&gt;            Write-Output "Multiple objects returned for $vmname, please specify a single VM"&lt;br /&gt;        } else {&lt;br /&gt;            write-output "VM Not found - $vmName"&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;} else {&lt;br /&gt;    write-output "ERROR: VI server not found - $viServer"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Write-Output (Get-Date -format "dd/MM/yyyy HH:mm:ss")&lt;br /&gt;&lt;br /&gt;Disconnect-VIServer -confirm:$false&lt;br /&gt;exit 0&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4463403549876742731?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4463403549876742731' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4463403549876742731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4463403549876742731'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/07/powercli-relocate-vm-storage-with-vi35.html' title='PowerCli Relocate VM storage with VI35 / VI4'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8506604358260259203</id><published>2009-07-01T22:51:00.000+10:00</published><updated>2009-07-01T22:51:43.707+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>PowerShell - vSphere VMKernel NIC MTU</title><content type='html'>I came across a problem with VI4 (vSphere) on ESXi, where I was unable to create a vmkernel NIC for iSCSI with the vicfg-vmknic.pl script to set a custom MTU of 9000.  This post provides a method using the GUI/perl script, and a PowerShell vSphere PowerCLI script to modify an existing VMKernel NIC.&lt;br /&gt;&lt;br /&gt;It seems there is a bug in the perl script doesn't allow you to create a VMKernel NIC, however it does work if you create one through the GUI, and then use the script to delete and re-create the virtual NIC.&lt;br /&gt;&lt;br /&gt;This was using a standalone ESXi server with a normal vSwitch - it wasn't managed by VC and it wasn't a DVS.&lt;br /&gt;&lt;br /&gt;The GUI/PL script method:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a VMKernel NIC in an existing vSwitch through the VI Client, with a port group called iSCSI1 in this example.&lt;/li&gt;&lt;li&gt;Using the CLI, run the following commands, the first to delete the existing NIC, and then another to re-create the same NIC, but with an increased MTU:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;vicfg-vmknic.pl -d iSCSI1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;vicfg-vmknic.pl -a -i x.x.x.x -n x.x.x.x -m 9000 iSCSI1&lt;/span&gt;&lt;/li&gt;&lt;li&gt;Run 'vicfg-vmknic.pl –l' to list the VMK NICs, which should show the adjusted MTU&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I wasn't particularly happy with this method, so I looked at using the vSphere PowerCLI to set the MTU.  For whatever reason, VMware chose not to expose the MTU property, which leaves only the SDK.&lt;br /&gt;&lt;br /&gt;Luckily the PowerCLI makes it much easier to use the .Net SDK than previously possible with the Get-View cmdlet, so the script below is a combination of standard PowerCLI with a hook into the vNIC collection and the UpdateVirtualNic method to change a virtual NIC spec.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;param (&lt;br /&gt;&lt;br /&gt;    $MTU = 9000, &lt;br /&gt;    $nicName = vmk1, &lt;br /&gt;    $vcServer = "vcServer", &lt;br /&gt;    $vmServerName = "esx01"&lt;br /&gt;)&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;#&lt;br /&gt;# Description:&lt;br /&gt;#  Update the MTU of a vmkernel NIC used for iSCSI&lt;br /&gt;#&lt;br /&gt;# Limitations:&lt;br /&gt;#  DVS untested&lt;br /&gt;#&lt;br /&gt;# Assumptions, this script works on the assumption that:&lt;br /&gt;#  The caller provides credentials with permissions to change the specified NIC&lt;br /&gt;#&lt;br /&gt;# Arguments:&lt;br /&gt;#  MTU, The new MTU size, eg. 9000&lt;br /&gt;#  nicName, The vmkernel NIC, eg. vmk1.  Note that this differs from the port group (eg. iSCSI1, with a NIC name of vmk1)&lt;br /&gt;#  vcServer, the VC instance to connect to, eg. vcServer&lt;br /&gt;#  vmServerName, The server name controlled by the VC instance (or direct), eg. esx01&lt;br /&gt;#&lt;br /&gt;# Usage:&lt;br /&gt;#  PowerShell . .\UpdateVMKMTU.ps1 -MTU 9000 -nicName 'vmk1' -vcServer 'vcServer' -vmServerName 'esx01'&lt;br /&gt;#&lt;br /&gt;# References:&lt;br /&gt;#  http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.VirtualNic.Specification.html&lt;br /&gt;#&lt;br /&gt;# Changes:&lt;br /&gt;#  26/06/2009, Wayne Martin, initial version&lt;br /&gt;&lt;br /&gt;#$ErrorActionPreference = "Continue"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Connect-VIServer -server $vcServer        # connect to VC&lt;br /&gt;$hostSystem = get-view -ViewType HostSystem -Filter @{"Name" = $vmServerName}   # Find the .Net view of the specified host&lt;br /&gt;$hostConfigManager = $hostSystem.get_ConfigManager()      # Get the config manager&lt;br /&gt;$hostNetworkSystem = $hostConfigManager.get_NetworkSystem()     # Find the MOR of the host network system&lt;br /&gt;$netSystem = Get-View $hostNetworkSystem       # Get the object from the reference for the update method later&lt;br /&gt;&lt;br /&gt;$hostconfig = $hostSystem.Config        # Get the current host config&lt;br /&gt;$hostNetwork = $hostconfig.Network        # Get the current network host config&lt;br /&gt;$hostvNIC = $hostNetwork.vNic         # Get the virtual NICs&lt;br /&gt;&lt;br /&gt;$nicBeingUpdated = $null&lt;br /&gt;foreach ($hostVirtualNIC in $hostvNIC) {       # For each virtual NIC&lt;br /&gt;    if ($hostVirtualNIC.Device -eq $nicName) {        # Is this the device specified?&lt;br /&gt;        $nicBeingUpdated = $hostVirtualNIC       # Yes, copy the object&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if ($nicBeingUpdated) {          # Was something found?&lt;br /&gt;    $nicSpec = $nicBeingUpdated.Spec        # Yes, get the current spec&lt;br /&gt;    $currentMTU = $nicSpec.MTU         # Get the current MTU from the spec&lt;br /&gt;&lt;br /&gt;    if ($currentMTU -ne $MTU) {         # Is the MTU different?&lt;br /&gt;        $nicSpec.set_Mtu($MTU)         # Yes, update the MTU on the copy of the spec of the existing NIC&lt;br /&gt;        $netSystem.UpdateVirtualNic($nicName, $nicSpec)             # Call the update method from the netsystem, to update the NIC with the modified device spec&lt;br /&gt;&lt;br /&gt;        write-output "MTU for $nicName updated from $currentMTU to $MTU"&lt;br /&gt;        (get-vmhostnetwork).VirtualNic        # Output updated information&lt;br /&gt;    } else {&lt;br /&gt;        write-output "MTU for $nicName already set to $MTU, no changes made"&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;} else {&lt;br /&gt;&lt;br /&gt;    write-output "NIC $nicName not found, no changes made"&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8506604358260259203?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8506604358260259203' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8506604358260259203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8506604358260259203'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/07/powershell-vsphere-vmkernel-nic-mtu.html' title='PowerShell - vSphere VMKernel NIC MTU'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-1949443810730590425</id><published>2009-06-28T15:16:00.003+10:00</published><updated>2009-09-05T07:31:46.369+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><title type='text'>Processor affinity on Windows server 2003/2008</title><content type='html'>This post describes a few methods of setting the processor affinity mask for a service, process or executable on a Windows Server 2003/2008 machine. There are several reasons to do this; increasingly as software becomes licensed per socket or even per core, but also separating or tuning the performance of applications on multi-core and hyper-threaded processors, i.e. to force usage of shared cache.&lt;br /&gt;&lt;br /&gt;Of course this can be done through the task manager GUI (taskmgr.exe), but following the theme of command-line automation and scripting, I’ve found a few other methods that may be more efficient. The options below have different advantages/disadvantages and really depend on what you’re trying to achieve and how the process gets started.&lt;br /&gt;&lt;br /&gt;In no particular order:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;WSRM &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use Windows System Resource Manager, which among other things can be used for persistent application to processor mappings. This requires 2003 enterprise, 2003 datacenter or server 2008. WSRM is useful when trying to run multiple applications on a single physical box, allowing granular control through a GUI (the configuration of which is persistent across reboots). WSRM also has a command-line interface, and can be used for accounting and to set per-processor utilisation, not just processor affinity.&lt;br /&gt;&lt;br /&gt;Note that when I was testing WSRM, it detected calc.exe and matched it against a rule to limit 50% CPU usage, but using factorial of a large number still resulted in 100% CPU. WSRM uses soft caps apparently, only constraining usage when there is contention (I didn’t do any more testing to confirm). There is also a note about WSRM only supporting management of non-OS processes (I’m unsure of whether it would detect calc.exe as such).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;PowerShell&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use PowerShell to set the processor affinity for one or more running processes. There’s an example script below, setting the processor mask of calc.exe to the first 4 processors. I like this method because the script is simple, it would be easy to schedule, works on x86 and x64, supports multiple processes of the same name and at least partly because it highlights just how easy administration with PowerShell is.&lt;br /&gt;&lt;br /&gt;Note that if you use factorial of a large number with calc.exe (n!) you’ll generate100% CPU which can be useful for testing. The mask below is 0xf = 1111 – a mask allowing use of only the first four processors:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;$calcSet = Get-Process -ProcessName "calc"&lt;br /&gt;foreach ($calc in $calcSet) {$calc.ProcessorAffinity=0xF}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Start or psexec&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use a wrapper to launch the process, including either ‘start /affinity’ or ‘psexec -a’ to launch the application, setting affinity as required. Note that ‘start /affinity’ is available on 2003 server, Vista and 2008 server, but not XP.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;psexec /a 0,1 calc.exe&lt;br /&gt;start /affinity 1 calc.exe&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you’re trying to control a service, you could use instsrv/srvany to create a service that wraps the start or psexec command around the real service binary. For example, the commands below create another version of the spooler service that will only run on the first processor.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;instsrv Test c:\util\srvany.exe&lt;br /&gt;reg add hklm\system\currentcontrolset\services\test\Parameters&lt;br /&gt;reg add hklm\system\currentcontrolset\services\test\Parameters /v Application /t reg_sz /d cmd.exe&lt;br /&gt;reg add hklm\system\currentcontrolset\services\test\Parameters /v AppParameters /t reg_sz /d "/c start /affinity 1 C:\WINDOWS\system32\spoolsv.exe"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;ImageCfg&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use imagecfg.exe - a Windows Server 2000 Resource Kit Supplement utility - to modify the binary to set the processor affinity. This actually modifies the .exe – changing the initialisation section of the executable, and will ensure the affinity whenever the executable is run. Note that in my testing, modifying an x64 binary with this utility did not set the affinity correctly, only x86 binaries were successful (running on x64 or x86 OS). If you’re using calc.exe to test this – use a copy in another folder, otherwise windows file protection will replace the updated binary, undoing any change you make.&lt;br /&gt;&lt;br /&gt;The mask below is 0xf = 1111 – a mask allowing use of only the first four processors:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;imagecfg -a 0x0F c:\temp\calc.exe&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;ProcAff.exe&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use procaff.exe (a third-party utility) to set the processor affinity of a running process. This could be run as startup scheduled task, setting the mask of any process started as a service (you might need to build in some logic to wait for the processes to start). Note that this utility worked on both x86 and x64 systems while testing, but it’s limited in that if there are multiple processes with the same name, it requires a PID. This is easy enough to script using a ‘for’ loop and pslist to identify the PIDs and then call procaff.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;procaff /set 1 calc.exe&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Boot.ini and HAL options&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Some rather more severe options – reducing the OS to only one CPU:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The /NUMPROC switch in boot.ini on the server.  This will set the number of processes Windows will see when booted.  I assume this will just apply a mask at startup, but in a multi-CPU multi-core server I haven't tested to confirm the cores are paired or whether the first core from each CPU is presented.&lt;/li&gt;&lt;li&gt;The /ONECPU switch in boot.ini on the server. This will tell Windows to use only one CPU, limiting any application running on the OS. On a multi-core server, the OS would use only one core of one package. I successfully tested this on 2003 enterprise OS. &lt;/li&gt;&lt;li&gt;Downgrade the OS from a multiprocessor HAL to a uniprocessor HAL, removing support for multiple CPUs from the OS. I didn’t actually test this method, but it’s something I used to do on NT4, and I don’t see why it wouldn’t work on 2003/2008. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Plug-and-Play device interrupts&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use Intfilter.exe - allowing you to perform similar functionality to drivers – binding interrupts to a particular processor, useful to control plug-and-play driver-level CPU binding.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Procaff&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.stefan-kuhr.de/cms/index.php?option=com_content&amp;amp;view=article&amp;amp;id=60&amp;amp;Itemid=77"&gt;&lt;span style="font-size:85%;"&gt;http://www.stefan-kuhr.de/cms/index.php?option=com_content&amp;amp;view=article&amp;amp;id=60&amp;amp;Itemid=77&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Boot INI Options Reference&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb963892.aspx"&gt;http://technet.microsoft.com/en-us/sysinternals/bb963892.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;HAL options after Windows XP or Windows Server 2003 Setup&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/309283"&gt;http://support.microsoft.com/kb/309283&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Available Switch Options for Windows NT Boot.ini File&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/170756"&gt;http://support.microsoft.com/kb/170756&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;How to Manually Add Support for a Second Processor&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/156358"&gt;http://support.microsoft.com/kb/156358&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows System Resource Manager: Frequently Asked Questions&lt;br /&gt;&lt;a href="http://www.microsoft.com/windowsserver2003/techinfo/overview/wsrmfaq.mspx"&gt;http://www.microsoft.com/windowsserver2003/techinfo/overview/wsrmfaq.mspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows System Resource Manager&lt;br /&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=848306EF-F57E-4B3F-984D-50E9BCA44383&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=848306EF-F57E-4B3F-984D-50E9BCA44383&amp;amp;displaylang=en&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Best Practices for Managing Applications with Process Control&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/library/bb742469.aspx"&gt;http://technet.microsoft.com/en-us/library/bb742469.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;The Context Switch Action (xperf)&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc305227.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc305227.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Monitoring Context Switches and Threads&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/library/cc938639.aspx"&gt;http://technet.microsoft.com/en-us/library/cc938639.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Analyzing Processor Activity&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/library/cc958310.aspx"&gt;http://technet.microsoft.com/en-us/library/cc958310.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Monitoring Activity on Multiprocessor Systems&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/library/cc938649.aspx"&gt;http://technet.microsoft.com/en-us/library/cc938649.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows Performance Toolkit x86 and x64 v4.1.1&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/e/2/7/e2700369-d072-4fdc-a451-c3355eab0613/xperf_x86.msi"&gt;http://download.microsoft.com/download/e/2/7/e2700369-d072-4fdc-a451-c3355eab0613/xperf_x86.msi&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://download.microsoft.com/download/e/2/7/e2700369-d072-4fdc-a451-c3355eab0613/xperf_x64.msi"&gt;http://download.microsoft.com/download/e/2/7/e2700369-d072-4fdc-a451-c3355eab0613/xperf_x64.msi&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows Performance Toolkit&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/cc305187.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc305187.aspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Intfilter to manage drivers:&lt;br /&gt;&lt;a href="http://support.microsoft.com/default.aspx?scid=KB;en-us;252867"&gt;http://support.microsoft.com/default.aspx?scid=KB;en-us;252867&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-1949443810730590425?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=1949443810730590425' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1949443810730590425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1949443810730590425'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/06/processor-affinity-on-windows-server.html' title='Processor affinity on Windows server 2003/2008'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8354429639557880553</id><published>2009-06-01T20:19:00.000+10:00</published><updated>2009-06-01T20:19:29.039+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>Calling CPUID from PowerShell for Intel VT</title><content type='html'>I was trying to work out whether the Intel VT (VMX) extensions had been enabled on a server and whether the server support the SSE4.1 and SSE4.2 processor instructions - without having to reboot the server to check the BIOS. I ended up 'writing' a PowerShell script that compiles some C# to call a DLL written in assembler which has run the CPUID instruction and returned the results. Note that I didn't really write any of this, the PowerShell script compiling and running the C# is from the reference below, as is the actual C$ and asm dll.&lt;br /&gt;&lt;br /&gt;Does this seem like a lot of effort? Sure does, but unfortunately the simple method - using Win32_Processor.ProcessorID was useless in this example, as for some reason MS chose to only return the EAX and EDX registers, whereas the bits I was after were returned in ECX. There may also be other ways to achieve this through PowerShell/.Net framework, rather than compiling c# to call unmanaged code.&lt;br /&gt;&lt;br /&gt;Below is the PowerShell script, which contains the inline C# that is compiled and executed, which in turn requires the dll, using the EFLAGS register to confirm support and the CPUID instruction with eax=1 (if further supported) to query feature information from the CPU.&lt;br /&gt;&lt;br /&gt;The original c# and asm dll: (see below for the hex text stream)&lt;br /&gt;&lt;a href="http://devpinoy.org/blogs/cvega/archive/2006/04/07/2658.aspx"&gt;http://devpinoy.org/blogs/cvega/archive/2006/04/07/2658.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The compile-csharp function: (adding the -unsafe parameter to allow pointer use)&lt;br /&gt;&lt;a href="http://monadblog.blogspot.com/2005/12/calling-win32-api-functions-through.html"&gt;http://monadblog.blogspot.com/2005/12/calling-win32-api-functions-through.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;#&lt;br /&gt;# Description:&lt;br /&gt;#  Call the CPUID function from an external DLL through C# inline code.&lt;br /&gt;#  Report whether Intel VT (VMX) is supported, bit 5 of the ECX register returned from CPUID eax=1 call.&lt;br /&gt;#  Note that WMI Win32_Processor:ProcessID contains the results of a call to CPUID - except that it only contains EAX and EDX, Intel VT (what I was after) is in ECX&lt;br /&gt;#&lt;br /&gt;# Author:&lt;br /&gt;#  Wayne Martin, note that I didn't write any of this code, the inline C# was from the monad reference below, and the CPUID DLL and C# was from the first reference&lt;br /&gt;&lt;br /&gt;#References:&lt;br /&gt;# cpuid.dll and the namespace from: http://devpinoy.org/blogs/cvega/archive/2006/04/07/2658.aspx&lt;br /&gt;# Intel cpuid: http://www.intel.com/Assets/PDF/appnote/241618.pdf&lt;br /&gt;# http://monadblog.blogspot.com/2005/12/calling-win32-api-functions-through.html&lt;br /&gt;# http://msdn.microsoft.com/en-us/library/aa394373.aspx&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function Compile-Csharp ([string] $code, $FrameworkVersion="v2.0.50727",&lt;br /&gt;[Array]$References)&lt;br /&gt;{&lt;br /&gt;    $cp = new-object Microsoft.CSharp.CSharpCodeProvider&lt;br /&gt;    $cpar = New-Object System.CodeDom.Compiler.CompilerParameters&lt;br /&gt;    $cpar.CompilerOptions = "-unsafe"      # unsafe to compile the code which uses pointers in the DLL call&lt;br /&gt;    $cpar.GenerateInMemory = $true&lt;br /&gt;    $cpar.GenerateExecutable = $false&lt;br /&gt;    $cpar.OutputAssembly = "custom"&lt;br /&gt;    # $cpar.ReferencedAssemblies.AddRange($refs)&lt;br /&gt;    $cr = $cp.CompileAssemblyFromSource($cpar, $code)&lt;br /&gt;&lt;br /&gt;    if ( $cr.Errors.Count)&lt;br /&gt;    {&lt;br /&gt;        $codeLines = $code.Split("`n");&lt;br /&gt;        foreach ($ce in $cr.Errors)&lt;br /&gt;        {&lt;br /&gt;            write-host "Error: $($codeLines[$($ce.Line - 1)])"&lt;br /&gt;            write-host $ce&lt;br /&gt;           # $ce out-default&lt;br /&gt;        }&lt;br /&gt;        Throw "INVALID DATA: Errors encountered while compiling code"&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$code = @'&lt;br /&gt;namespace CPUID&lt;br /&gt;{&lt;br /&gt; using System;&lt;br /&gt; using System.Runtime.InteropServices;&lt;br /&gt; using System.Text;&lt;br /&gt;&lt;br /&gt; public class cpuid&lt;br /&gt; {&lt;br /&gt;  private cpuid()&lt;br /&gt;  {&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  [DllImport("cpuid.dll")]&lt;br /&gt;     public static extern bool CPUIDIsSupported();&lt;br /&gt;&lt;br /&gt;  [DllImport("cpuid.dll")]&lt;br /&gt;     private unsafe static extern bool __cpuid&lt;br /&gt;            (uint function, &lt;br /&gt;             int* eax, &lt;br /&gt;             int* ebx, &lt;br /&gt;             int* ecx, &lt;br /&gt;             int* edx);&lt;br /&gt;&lt;br /&gt;  // Invoke __cpuid function&lt;br /&gt;  public unsafe static bool Invoke&lt;br /&gt;      (uint level, &lt;br /&gt;       out int eax, &lt;br /&gt;       out int ebx, &lt;br /&gt;       out int ecx, &lt;br /&gt;       out int edx)&lt;br /&gt;  {&lt;br /&gt;   int __eax = 0;&lt;br /&gt;   int __ebx = 0;&lt;br /&gt;   int __ecx = 0;&lt;br /&gt;   int __edx = 0;&lt;br /&gt;&lt;br /&gt;   if (__cpuid(level, &amp;amp;__eax, &amp;amp;__ebx, &amp;amp;__ecx, &amp;amp;__edx))&lt;br /&gt;   {&lt;br /&gt;    eax = __eax;&lt;br /&gt;    ebx = __ebx;&lt;br /&gt;    ecx = __ecx;&lt;br /&gt;    edx = __edx;&lt;br /&gt;&lt;br /&gt;    return true;&lt;br /&gt;   }&lt;br /&gt;   else&lt;br /&gt;   {&lt;br /&gt;    eax = 0;&lt;br /&gt;    ebx = 0;&lt;br /&gt;    ecx = 0;&lt;br /&gt;    edx = 0;&lt;br /&gt;&lt;br /&gt;    return false;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;'@&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;compile-CSharp $code&lt;br /&gt;$eax = ""&lt;br /&gt;$ebx = ""&lt;br /&gt;$ecx = ""&lt;br /&gt;$edx = ""&lt;br /&gt;[CPUID.CPUID]::Invoke(1, [ref]$eax, [ref]$ebx, [ref]$ecx, [ref]$edx) &lt;br /&gt;&lt;br /&gt;$INTEL_CPUID_VT_FLAG = 0x0020                                                           # bit 5 of ECX returned from CPUID EAX=1&lt;br /&gt;$INTEL_CPUID_SSE41 = 0x80000                                                            # bit 19 of ECX returned from CPUID EAX=1&lt;br /&gt;$INTEL_CPUID_SSE42 = 0x100000                                                           # bit 20 of ECX returned from CPUID EAX=1&lt;br /&gt;$INTEL_CPUID_XD = 0x00100000&lt;br /&gt;&lt;br /&gt;write-output ("Intel VT: " + ($ecx -band $INTEL_CPUID_VT_FLAG) )                        # Does this processor support Intel VT / VMX?&lt;br /&gt;write-output ("SSE 4.1: " + ($ecx -band $INTEL_CPUID_SSE41) )                           # Does this processor support SSE 4.1?&lt;br /&gt;write-output ("SSE 4.2: " + ($ecx -band $INTEL_CPUID_SSE42) )                           # Does this processor support SSE 4.2?&lt;br /&gt;write-output ("eXecute Disable: " + ($edx -band $INTEL_CPUID_XD) )                      # Does this processor support XD?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Note that in a previous post, I have written two powershell scripts, one to convert binary to a hex string, and vice versa. The following stream is the cpuid.dll file, if you write it to cpuid.txt and run the following command it will create the dll:&lt;br /&gt;&lt;br /&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;Powershell . .\HexStringToBinary.ps1 cpuid.txt cpuid.dll&lt;br /&gt;&lt;br /&gt;4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000c00000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a240000000000000071d4f7db35b5998835b5998835b59988c9958b8834b59988bbaa8a8834b599885269636835b59988000000000000000000000000000000000000000000000000504500004c0103006a793a440000000000000000e0000e210b01050c00020000000400000000000000100000001000000020000000000010001000000002000004000000040000000400000000000000004000000004000070fa000002000000000010000010000000001000001000000000000010000000002000005f0000000000000000000000000000000000000000000000000000000000000000000000003000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002e746578740000006c000000001000000002000000040000000000000000000000000000200000602e726461746100005f000000002000000002000000060000000000000000000000000000400000402e72656c6f6300000c000000003000000002000000080000000000000000000000000000400000420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000558becb801000000c9c20c005352b8000000009c588bc83500002000509d9c5b33c325000020007507b801000000eb0233c0519d5a5bc3558bec5357e8cbffffff48740433c0eb1e8b45080fa28b7d0c89078b7d14890f8b7d1889178b7d10891fb8010000005f5bc9c214000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a793a44000000003c2000000100000002000000020000002820000030200000382000000c1000003710000046200000572000000000010063707569642e646c6c0043505549444973537570706f72746564005f5f6370756964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8354429639557880553?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8354429639557880553' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8354429639557880553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8354429639557880553'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/06/calling-cpuid-from-powershell-for-intel.html' title='Calling CPUID from PowerShell for Intel VT'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7162025969615736968</id><published>2009-05-30T10:45:00.003+10:00</published><updated>2009-05-30T10:52:28.211+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>Extending a server 2003 VM system/boot disk</title><content type='html'>Whether using basic or dynamic disks, Windows Server 2003 doesn’t provide a method to extend the size of the system or boot disk. In VI35, I have used the following process to extend the system/boot disk of 2003 server virtual machines. Note that this is for the system/boot disk only, data volumes can be grown and extended live.&lt;br /&gt;&lt;br /&gt;This process requires the VM to be shutdown, then a small outage while the disk is extended, then a reboot once the OS is first started.&lt;br /&gt;&lt;br /&gt;The process I used in VI 3.5 U4, with a 2003 SP2 virtual machine:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Turn the VM off - VM1 in this example &lt;/li&gt;&lt;li&gt;Use VC to increase the size of the boot/system disk of VM1 by xGB (6 in my test) &lt;/li&gt;&lt;li&gt;Use VC to attach the disk inside another running VM that can be shutdown, eg. VM2 &lt;/li&gt;&lt;li&gt;On VM2, load diskmgmt.msc, rescan disks (or run diskpart rescan) &lt;/li&gt;&lt;li&gt;On VM2, start diskpart:&lt;br /&gt;&lt;ol type="a"&gt;&lt;li&gt;List vol (get a list of volumes)&lt;br /&gt;&lt;li&gt;Select vol x (where x is the number of the newly added disk)&lt;br /&gt;&lt;li&gt;Extend &lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Shutdown VM2 and detach the disk (don’t delete it!)&lt;/li&gt;&lt;li&gt;Start VM1&lt;/li&gt;&lt;li&gt;On my test, after logon, a setupapi message ‘Windows has finished installing new devices. Do you want to restart your computer now?’. &lt;/li&gt;&lt;li&gt;Said yes and the server restarted, diskmgmt.msc shows correctly sized disk. &lt;/li&gt;&lt;li&gt;Ran chkdsk c: to verify no corruption &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Step 8 has a matching event ID 271 from PlugPlayManager and setupapi.log entry:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-size:78%;"&gt;The Plug and Play operation cannot be completed because a device driver is&lt;br /&gt;preventing the device from stopping. The name of the device driver is listed as&lt;br /&gt;the vetoing service name below.&lt;br /&gt;Vetoed device:&lt;br /&gt;STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00&lt;br /&gt;Vetoing device:&lt;br /&gt;STORAGE\Volume\1&amp;amp;30a96598&amp;amp;0&amp;amp;Signature6AF3AEFAOffset7E00Length53FD06C00&lt;br /&gt;Vetoing service name: FileSystem\Ntfs&lt;br /&gt;Veto type 6: PNP_VetoDevice&lt;br /&gt;When Windows attempts to install, upgrade, remove, or reconfigure a device,&lt;br /&gt;it queries the driver responsible for that device to confirm that the operation&lt;br /&gt;can be performed. If any of these drivers denies permission (query-removal&lt;br /&gt;veto), then the computer must be restarted in order to complete the operation.&lt;br /&gt;User Action&lt;br /&gt;Restart your computer.&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;br /&gt;Setupapi.log driver logging showing the first vetoed attempt at installation and then the shadow copy volume snapshot install:&lt;br /&gt;&lt;span style="font-size:78%;"&gt;[2009/05/06 08:45:46 404.3 Driver Install]&lt;br /&gt;#-019 Searching for hardware ID(s): storage\volume&lt;br /&gt;#-198 Command line processed: C:\WINDOWS\system32\services.exe&lt;br /&gt;#I393 Modified INF cache "C:\WINDOWS\inf\INFCACHE.1".&lt;br /&gt;#W383 "volume.PNF" migrate: PNF Language = 0409, Thread = 0c09.&lt;br /&gt;#I022 Found "STORAGE\Volume" in C:\WINDOWS\inf\volume.inf; Device: "Generic volume"; Driver: "Generic volume"; Provider: "Microsoft"; Mfg: "Microsoft"; Section name: "volume_install".&lt;br /&gt;#I023 Actual install section: [volume_install.NTx86]. Rank: 0x00000000. Driver date: 10/01/2002. Version: 5.2.3790.3959.&lt;br /&gt;#-166 Device install function: DIF_SELECTBESTCOMPATDRV.&lt;br /&gt;#I063 Selected driver installs from section [volume_install] in "c:\windows\inf\volume.inf".&lt;br /&gt;#I320 Class GUID of device remains: {71A27CDD-812A-11D0-BEC7-08002BE2092F}.&lt;br /&gt;#I060 Set selected driver.&lt;br /&gt;#I058 Selected best compatible driver.&lt;br /&gt;#-166 Device install function: DIF_INSTALLDEVICEFILES.&lt;br /&gt;#I124 Doing copy-only install of "STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00".&lt;br /&gt;#-166 Device install function: DIF_REGISTER_COINSTALLERS.&lt;br /&gt;#I056 Coinstallers registered.&lt;br /&gt;#-166 Device install function: DIF_INSTALLINTERFACES.&lt;br /&gt;#-011 Installing section [volume_install.NTx86.Interfaces] from "c:\windows\inf\volume.inf".&lt;br /&gt;#I054 Interfaces installed.&lt;br /&gt;#-166 Device install function: DIF_INSTALLDEVICE.&lt;br /&gt;#I123 Doing full install of "STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00".&lt;br /&gt;#W100 Query-removal during install of "STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00" was vetoed by "STORAGE\Volume\1&amp;amp;30a96598&amp;amp;0&amp;amp;Signature6AF3AEFAOffset7E00Length53FD06C00" (veto type 6: PNP_VetoDevice).&lt;br /&gt;#W104 Device "STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00" required reboot: Query remove failed (install) CfgMgr32 returned: 0x17: CR_REMOVE_VETOED.&lt;br /&gt;#I121 Device install of "STORAGE\VOLUME\1&amp;amp;30A96598&amp;amp;0&amp;amp;SIGNATURE6AF3AEFAOFFSET7E00LENGTH53FD06C00" finished successfully.&lt;br /&gt;[2009/05/06 08:55:18 400.3 Driver Install]&lt;br /&gt;#-019 Searching for hardware ID(s): storage\volumesnapshot&lt;br /&gt;#-198 Command line processed: C:\WINDOWS\system32\services.exe&lt;br /&gt;#W383 "volsnap.PNF" migrate: PNF Language = 0409, Thread = 0c09.&lt;br /&gt;#I022 Found "STORAGE\VolumeSnapshot" in C:\WINDOWS\inf\volsnap.inf; Device: "Generic volume shadow copy"; Driver: "Generic volume shadow copy"; Provider: "Microsoft"; Mfg: "Microsoft"; Section name: "volume_snapshot_install".&lt;br /&gt;#I023 Actual install section: [volume_snapshot_install.NTx86]. Rank: 0x00000000. Driver date: 10/01/2002. Version: 5.2.3790.3959.&lt;br /&gt;#-166 Device install function: DIF_SELECTBESTCOMPATDRV.&lt;br /&gt;#I063 Selected driver installs from section [volume_snapshot_install] in "c:\windows\inf\volsnap.inf".&lt;br /&gt;#I320 Class GUID of device remains: {533C5B84-EC70-11D2-9505-00C04F79DEAF}.&lt;br /&gt;#I060 Set selected driver.&lt;br /&gt;#I058 Selected best compatible driver.&lt;br /&gt;#-166 Device install function: DIF_INSTALLDEVICEFILES.&lt;br /&gt;#I124 Doing copy-only install of "STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT1".&lt;br /&gt;#-166 Device install function: DIF_REGISTER_COINSTALLERS.&lt;br /&gt;#I056 Coinstallers registered.&lt;br /&gt;#-166 Device install function: DIF_INSTALLINTERFACES.&lt;br /&gt;#-011 Installing section [volume_snapshot_install.NTx86.Interfaces] from "c:\windows\inf\volsnap.inf".&lt;br /&gt;#I054 Interfaces installed.&lt;br /&gt;#-166 Device install function: DIF_INSTALLDEVICE.&lt;br /&gt;#I123 Doing full install of "STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT1".&lt;br /&gt;#I121 Device install of "STORAGE\VOLUMESNAPSHOT\HARDDISKVOLUMESNAPSHOT1" finished successfully.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;References &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;How to extend a data volume in Windows Server 2003, in Windows XP, in Windows 2000, and in Windows Server 2008&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/325590"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/325590&lt;/span&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7162025969615736968?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7162025969615736968' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7162025969615736968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7162025969615736968'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/05/extending-server-2003-vm-systemboot.html' title='Extending a server 2003 VM system/boot disk'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-5257235109719994576</id><published>2009-05-16T17:26:00.000+10:00</published><updated>2009-05-16T17:26:18.128+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>Generating 100% CPU with calc or PowerShell</title><content type='html'>Occasionally when testing something I want to generate 100% CPU load on a Windows computer. There are several utilities out there to do this, but that implies you have the utility on hand and are comfortable running it on the server. A colleague of mine (thanks Mark S.) showed me this nifty trick of using calc.exe to generate 100% CPU. The best thing about this is that every standard Windows OS installation has calc.exe.&lt;br /&gt;&lt;br /&gt;This post provides two methods of generating 100% CPU load, the original calc.exe method, and a simple one line PowerShell command to do the same thing from the command-line (locally or on a remote server with PS v1 and psexec). Note that there may be a better method with PowerShell, I simply scripted the same operation calc was performing.&lt;br /&gt;&lt;br /&gt;On dual-CPU/core computers this uses 100% of one CPU/core. To use more than that, calc or the PowerShell command can be run more than once, and Windows by default will run the new process on another less-busy CPU/core.&lt;br /&gt;&lt;br /&gt;One practical application of this is to load-test a VMware VI3 cluster, generating 100% CPU on one or more VMs to see how ESX and DRS/VC handles the load. I have also used this in the past when testing multi-threaded applications and processor affinity to see how Windows allocates a processor.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;calc.exe&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Use calc to calculate the factorial of a number - the product of all integers from 1 up to and including the number specified, eg 5! = 1x2x3x4x5&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Run calc.exe and switch to scientific mode&lt;/li&gt;&lt;li&gt;Type a large number (eg. 12345678901234567890), press the 'n!' button.&lt;/li&gt;&lt;li&gt;Calc will ask to confirm after warning this will take a very long time&lt;/li&gt;&lt;li&gt;100% CPU utilisation will now occur (essentially forever)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;strong&gt;PowerShell&lt;/strong&gt;&lt;br /&gt;&amp;nbsp;&lt;/div&gt;Using the largest int32 positive integer, calculate the factorial to generate 100% CPU utilisation &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;$result = 1; foreach ($number in 1..2147483647) {$result = $result * $number};&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Depending on how fast the CPU is, this could finish, so a loop to run the command above 2 billion times:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;foreach ($loopnumber in 1..2147483647) {$result=1;foreach ($number in 1..2147483647) {$result = $result * $number};$result}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you want to see how long the command takes to run:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Measure-Command {$result = 1; foreach ($number in 1..2147483647) {$result = $result * $number}}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Using the command-line then provides the ability to run the command remotely. To use psexec to remotely execute powershell v1 factorial to generate 100% CPU:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;psexec \\%computername% /s cmd /c "echo. | powershell $result = 1; foreach ($number in 1..2147483647) {$result = $result * $number}"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-5257235109719994576?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=5257235109719994576' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5257235109719994576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5257235109719994576'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/05/generating-100-cpu-with-calc-or.html' title='Generating 100% CPU with calc or PowerShell'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-6550387796561070734</id><published>2009-05-04T07:14:00.000+10:00</published><updated>2009-05-04T07:14:24.443+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>Converting VHD to VMDK SCSI for ESX</title><content type='html'>I had problems converting a 2003 server VHD to a vmdk that I could import into a VM running on ESX. I used WinImage to convert eh VHD-&amp;gt;VMDK, but it seems WinImage creates the VMDK as an IDE device, which is unsupported by ESX. I'm sure there are better ways to do this, such as satisfying whatever the pre-requisites are to getting VMware converter to automatically inject the drivers, but it was interesting doing it manually.&lt;br /&gt;&lt;br /&gt;Below is information on the process that I thought would have worked automatically, followed by the manual steps I took to make it work.&lt;br /&gt;&lt;br /&gt;To convert the vmdk, the following process was first tried to get VMware converter to convert the IDE disk to something ESX would recognise:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;1. Use WinImage to create the vmdk from the vhd&lt;/li&gt;&lt;li&gt;2. Use a VMware workstation VMX, including the disk as an IDE device. (a modified vmx is fine you don’t actually need VMware workstation)&lt;/li&gt;&lt;li&gt;3. Use VMware converter to import the workstation VMX into VC&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;I thought this would have been enough, but the VMware Converter process failed at 95% saying that it couldn’t find symmpi.sys. Symmpi.sys is the LSI Logic SCSI driver for the virtual SCSI adapter. I’m guessing that running VMware converter should automatically inject the drivers into the vmdk but couldn’t in this scenario (maybe because my local PC didn’t have the driver, or maybe because the driver cache cab files containing symmpi.sys weren’t on the target vmdk).&lt;br /&gt;&lt;br /&gt;Powering on the machine resulted in a stop 0x7b inaccessible disk error. To manually fix the problem, I then:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Added the disk to another VM. When starting the VM it warned that the new disk was created for LSI not buslogic. I said yes to convert to buslogic (which this VM was using as opposed to LSI).&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;The drive was then accessible through the VM, and I added the drivers (file and registry):&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Copied the driver file to the drivers directory: copy "\\%workingVM%\c$\WINDOWS\system32\drivers\symmpi.sys" "%mountedDrive%:\WINDOWS\system32\drivers"&lt;/li&gt;&lt;li&gt;Copied the driver cache files to the machine from a working 2003: copy "\\%workingVM%\c$\WINDOWS\Driver Cache\i386\*.*" "%mountedDrive%:\WINDOWS\Driver Cache\i386"&lt;/li&gt;&lt;li&gt;Exported the HKLM\SYSTEM\CurrentControlSet\Services\symmpiregistry and HKLM\SYSTEM\CurrentControlSet\Control\CriticalDeviceDatabase\pci#ven_1000&amp;amp;dev_0030 entries from a working server as regedit4 files (not Unicode).&lt;/li&gt;&lt;li&gt;Loaded the %mountedDrive%:\windows\system32\config\system registry hive on the disk to HKLM\VM: reg load HKLM\VM %mountedDrive%:\windows\system32\config\system&lt;/li&gt;&lt;li&gt;Modified the reg files to match the path the hive was loaded to (eg HKLM\VM\controlset001 instead of HKLM\system\currentcontrolset). The modified reg files are included below.&lt;/li&gt;&lt;li&gt;Imported the registry files which modified the loaded system hive on the disk&lt;/li&gt;&lt;li&gt;Disconnected the hive, shutdown the VM and disconnected the disk from the VM and reattached to the server created during the VMware Converter process&lt;/li&gt;&lt;li&gt;Turned on the server and was prompted to convert the disk type back to LSI (which I did).&lt;/li&gt;&lt;li&gt;The server started normally&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;div&gt;Note that the conversion between buslogic and LSI logic in both directions&amp;nbsp;were only required because the virtual machine that I mounted the disk on had a different adapter type.&lt;br /&gt;&lt;/div&gt;---&lt;br /&gt;&lt;br /&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;REGEDIT4&lt;br /&gt;[HKEY_LOCAL_MACHINE\VM\ControlSet001\Services\symmpi]&lt;br /&gt;"ErrorControl"=dword:00000001&lt;br /&gt;"Group"="SCSI miniport"&lt;br /&gt;"Start"=dword:00000000&lt;br /&gt;"Type"=dword:00000001&lt;br /&gt;"ImagePath"=hex(2):73,79,73,74,65,6d,33,32,5c,44,52,49,56,45,52,53,5c,73,79,6d,\&lt;br /&gt;6d,70,69,2e,73,79,73,00&lt;br /&gt;"Tag"=dword:00000021&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\VM\ControlSet001\Services\symmpi\Parameters]&lt;br /&gt;"BusType"=dword:00000001&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\VM\ControlSet001\Services\symmpi\Parameters\PnpInterface]&lt;br /&gt;"5"=dword:00000001&lt;br /&gt;&lt;br /&gt;[HKEY_LOCAL_MACHINE\VM\ControlSet001\Services\symmpi\Enum]&lt;br /&gt;"0"="PCI\\VEN_1000&amp;amp;DEV_0030&amp;amp;SUBSYS_00000000&amp;amp;REV_01\\3&amp;amp;61aaa01&amp;amp;0&amp;amp;80"&lt;br /&gt;"Count"=dword:00000001&lt;br /&gt;"NextInstance"=dword:00000001&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;REGEDIT4&lt;br /&gt;[HKEY_LOCAL_MACHINE\VM\ControlSet001\Control\CriticalDeviceDatabase\pci#ven_1000&amp;amp;dev_0030]&lt;br /&gt;"Service"="symmpi"&lt;br /&gt;"ClassGUID"="{4D36E97B-E325-11CE-BFC1-08002BE10318}"&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;References:&lt;br /&gt;Injecting SCSI controller device drivers into Windows&lt;br /&gt;&lt;a href="http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&amp;amp;cmd=displayKC&amp;amp;externalId=1005208"&gt;http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&amp;amp;cmd=displayKC&amp;amp;externalId=1005208&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Troubleshooting a virtual machine that fails to boot with STOP 0x7B error&lt;br /&gt;&lt;a href="http://kb.vmware.com/selfservice/viewContent.do?externalId=1006295&amp;amp;sliceId=1"&gt;http://kb.vmware.com/selfservice/viewContent.do?externalId=1006295&amp;amp;sliceId=1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-6550387796561070734?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=6550387796561070734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/6550387796561070734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/6550387796561070734'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/05/converting-vhd-to-vmdk-scsi-for-esx.html' title='Converting VHD to VMDK SCSI for ESX'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4992311774250594092</id><published>2009-05-02T21:37:00.003+10:00</published><updated>2009-05-02T21:46:18.147+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>VMware VI3 iSCSI with multiple non-HBA NICs</title><content type='html'>While researching iSCSI on VI3, I came across some interesting information when using the ESX iSCSI software initiator that would be applicable to many installations, highlighting a potential bottleneck.&lt;br /&gt;&lt;br /&gt;The short version is that if you’re using the iSCSI software initiator connecting to a single iSCSI target, multiple uplinks in an ESX network team for the VMKernel iSCSI port would not be used for load balancing.&lt;br /&gt;&lt;br /&gt;This can be easily proven by connecting to the service console and running esxtop (n) to view the traffic for individual network adapters. Assuming your storage is in use, one or more physical uplinks for the vSwitch handling iSCSI should be showing traffic. You can also use resxtop through the RCLI on ESXi.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Why this happens &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;My understanding is that current ESX software initiated iSCSI connections have a 1:1 relationship between NIC and iSCSI targets. An iSCSI target in this sense is a connection to the IP-based SAN storage, not LUN targets. This limitation applies when the SAN presents a single IP address for connectivity.&lt;br /&gt;&lt;br /&gt;VI3 software initiated iSCSI doesn’t support multipathing, which within ESX leaves only load balancing the physical uplinks in a team. Unfortunately, that leaves load balancing up to the vSwitch load balancing policy exceptions. I don’t believe any of the three choices fit most scenarios when connectivity to the iSCSI is through a single MAC/IP:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Route based on the originating virtual switch port ID, based on virtual port ID, of which there is only one VMKernel iSCSI port &lt;/li&gt;&lt;li&gt;Route based on source MAC hash, based on source MAC, of which there is only one &lt;/li&gt;&lt;li&gt;Route based on IP hash, based on layer 3 source-destination IP pair, of which there is only one (VMKernel -&gt; iSCSI virtual address). I don’t think this is a generally recommended load balancing approach anyway &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Link aggregation&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The VI3 SAN Deploy guide does state that one connection is established to each target. This seems to indicate one connection per LUN target, but the paragraph starts with software iSCSI and switches half way through to discuss iSCSI HBA’s.&lt;br /&gt;&lt;br /&gt;I’m still unsure of whether software iSCSI has multiple TCP sessions, one per target (I don’t believe this is the case). The blog referenced below also talks about 802.3 link aggregation which states the ESX 3.x software initiator does not support multiple TCP sessions.&lt;br /&gt;&lt;br /&gt;However, if multiple TCP sessions were being established for the iSCSI software initiator to a single target IP address, this opens the possibility of link aggregation at the physical switch. When using 802.3ad LACP in this IP-IP scenario, the switches would have to distribute connections based on the hash of TCP source/destination ports, rather than just IP/MAC.&lt;br /&gt;&lt;br /&gt;The following excerpt from the SAN deploy guide:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Software iSCSI initiators establish only one connection to each target. &lt;/p&gt;&lt;p&gt;Therefore, storage systems with a single target that contains multiple LUNs have all LUN traffic routed through that one connection. In a system that has two targets, with one LUN each, two connections are established between the ESX host and the two available volumes. For example, when aggregating storage traffic from multiple connections on an ESX host equipped with multiple iSCSI HBAs, traffic for one target can be set to a specific HBA, while traffic for another target uses a different HBA. For more information, see the “Multipathing” section of the iSCSI SAN Configuration Guide. Currently, VMware ESX provides active/passive multipath capability. NIC teaming paths do not appear as multiple paths to storage in ESX host configuration displays, however. NIC teaming is handled entirely by the network layer and must be configured and monitored separately from ESX SCSI storage multipath configuration. &lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;VI4/vSphere &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Excerpts from the following blog, indicate that changes in vSphere for software iSCSI to support multiple iSCSI sessions, allowing multipathing or link aggregation, which would allow separate iSCSI TCP sessions to be spread across more than one NICs (depending on how many iSCSI sessions).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://virtualgeek.typepad.com/virtual_geek/2009/01/a-multivendor-post-to-help-our-mutual-iscsi-customers-using-vmware.html"&gt;http://virtualgeek.typepad.com/virtual_geek/2009/01/a-multivendor-post-to-help-our-mutual-iscsi-customers-using-vmware.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The current experience discussed above (all traffic across one NIC per ESX host):&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;VMware can’t be accused of being unclear about this. Directly in the iSCSI SAN Configuration Guide: ESX Server‐based iSCSI initiators establish only one connection to each target. &lt;strong&gt;This means storage systems with a single target containing multiple LUNs have all LUN traffic on that one connection&lt;/strong&gt;, but in general, in my experience, this is relatively unknown. &lt;/p&gt;&lt;p&gt;This usually means that customers find that for a single iSCSI target (and however many LUNs that may be behind that target – 1 or more), they can’t drive more than 120-160MBps. This shouldn’t make anyone conclude that iSCSI is not a good choice or that 160MBps is a show-stopper. For perspective I was with a VERY big customer recently (more than 4000 VMs on Thursday and Friday two weeks ago) and their comment was that for their case (admittedly light I/O use from each VM) this was working well. Requirements differ for every customer. &lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;The changes in vSphere:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;p&gt;Now, this behavior will be changing in the next major VMware release. Among other improvements, &lt;strong&gt;the iSCSI initiator will be able to use multiple iSCSI sessions (hence multiple TCP connections)&lt;/strong&gt;. Looking at our diagram, this corresponds with “multiple purple pipes”for a single target. It won’t support MC/S or “multiple orange pipes per each purple pipe” – but in general this is not a big deal (large scale use of MC/S has shown a marginal higher efficiency than MPIO at very high end 10GbE configurations) . &lt;/p&gt;&lt;p&gt;&lt;strong&gt;Multiple iSCSI sessions will mean multiple “on-ramps” for MPIO (and multiple “conversations” for Link Aggregation)&lt;/strong&gt;. The next version also brings core multipathing improvements in the vStorage initiative (improving all block storage): NMP round robin, ALUA support, and EMC PowerPath for VMware which integrates into the MPIO framework and further improves multipathing. In the spirit of this post, EMC is working to make PowerPath for VMware as heterogeneous as we can. &lt;/p&gt;&lt;p&gt;Together – multiple iSCSI sessions per iSCSI target and improved multipathing means aggregate throughput for a single iSCSI target above that 160MBps mark in the next VMware release, as people are playing with now. Obviously we’ll do a follow up post.&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4992311774250594092?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4992311774250594092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4992311774250594092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4992311774250594092'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/05/vmware-vi3-iscsi-with-multiple-non-hba.html' title='VMware VI3 iSCSI with multiple non-HBA NICs'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3176205461370753084</id><published>2009-03-05T22:08:00.002+10:00</published><updated>2009-03-05T22:15:13.304+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workstation'/><title type='text'>Vista Sidebar Gadget for SiteMeter</title><content type='html'>This post provides a Vista Sidebar gadget to report on sitemeter information for a web site being monitored. In a previous post I’ve provided a command-line PowerShell method to retrieve the same information, but I thought I’d try this GUI thing people keep talking about.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;This is a very simple Vista sidebar gadget, it doesn’t have settings, or fly-outs, or links, or any other bits of cleverness, it was really just my first look into how Vista gadgets work. All I did was take the Microsoft hello-world example gadget and add a bit of javascript to (badly) scrape the sitemeter web page.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The gadget:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Has a transparent PNG background image and writes the text in white on two lines, with a gadget size of 128x64&lt;/li&gt;&lt;li&gt;Uses the MSXML DOM to issue a HTTP GET and for the sitemeter URL, using an asynchronous callback&lt;/li&gt;&lt;li&gt;Parses the HTTP response, looking for the first index of the word ‘Today’ and extracts the number&lt;/li&gt;&lt;li&gt;Updates the second field in the gadget with the current date/time to tell when the last successful get occurred&lt;/li&gt;&lt;li&gt;Uses the SetTimeout method to sleep for an hour before calling the getData() function again&lt;/li&gt;&lt;/ol&gt;What the gadget doesn’t do that could make this better:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Have the URL and timeouts stored in a settings file to save having to modify the JS when scraping a different URL or changing the timeout.&lt;/li&gt;&lt;li&gt;Have a flyout or something which shows the other summary information on the sitemeter page&lt;/li&gt;&lt;li&gt;Use a separate CSS and init() function rather than the in-line code from the example&lt;/li&gt;&lt;/ol&gt;To create this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Download the gadget samples from &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=b1e14e4f-3108-4c57-8b78-1157ca40dcc2"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=b1e14e4f-3108-4c57-8b78-1157ca40dcc2&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Copy SDK_HelloWorld.gadget to *.zip&lt;/li&gt;&lt;li&gt;Unzip the contents of the gadget zip file to a working directory and remove the read-only attribute from the files&lt;/li&gt;&lt;li&gt;Create a transparent PNG background 64x64 in size (or use the one provided in this post), and overwrite Background.png&lt;/li&gt;&lt;li&gt;Update images\aerologo.PNG with the png from this post&lt;/li&gt;&lt;li&gt;Update HelloWorld.html with the contents below:&lt;/li&gt;&lt;li&gt;Update the height and width to 128x64 &lt;br /&gt;- Add the script tag:&lt;script src="js/SiteMeter.js" type="text/javascript"&gt;&lt;/script&gt; &lt;br /&gt;- Update the in-place init() funciton to call getData()&lt;br /&gt;- Create SiteMeter.js with the contents below&lt;/li&gt;&lt;li&gt;Create a new directory and copy all of the gadget files to "%Systemdrive%\users\%username%\appdata\local\microsoft\Windows Sidebar\gadgets\SiteMeterCounter.gadget"&lt;/li&gt;&lt;li&gt;Update the URL in SiteMeter.js with the page to scrape&lt;/li&gt;&lt;li&gt;Add the gadget&lt;/li&gt;&lt;/ol&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_ErSjACRvSfI/Sa-_O_cH_bI/AAAAAAAAEY0/qciEB36wG68/s1600-h/Background.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; border: 1px solid black; border-width:1;"&gt;&lt;img border="1" src="http://4.bp.blogspot.com/_ErSjACRvSfI/Sa-_O_cH_bI/AAAAAAAAEY0/qciEB36wG68/s200/Background.png" vi="true" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_ErSjACRvSfI/Sa-_dIBAZHI/AAAAAAAAEY8/0IP4gTLaSXo/s1600-h/aerologo.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_ErSjACRvSfI/Sa-_dIBAZHI/AAAAAAAAEY8/0IP4gTLaSXo/s200/aerologo.PNG" vi="true" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;HelloWorld.html&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt; *************************************************************************&lt;br /&gt; *&lt;br /&gt; * Name: SiteMeter.html&lt;br /&gt; *&lt;br /&gt; * Description: &lt;br /&gt; * Simple SiteMeter counter&lt;br /&gt; * Displays the current count of today's visitors from the provided SiteMeter URL&lt;br /&gt; * &lt;br /&gt; *&lt;br /&gt; * Modified from the 'Hello World' Microsoft example &lt;br /&gt; ************************************************************************&lt;br /&gt;--&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;    &amp;lt;head&amp;gt;&lt;br /&gt;     &amp;lt;title&amp;gt;SiteMeter Count&amp;lt;/title&amp;gt;&lt;br /&gt;     &amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;      body&lt;br /&gt;      {&lt;br /&gt;          width: 128px;&lt;br /&gt;          height: 64px;&lt;br /&gt;                        font-family: calibri;&lt;br /&gt;                        color: white; &lt;br /&gt;      }&lt;br /&gt;      #gadgetContent&lt;br /&gt;      {&lt;br /&gt;          width: 128px;&lt;br /&gt;                        top: 3px;&lt;br /&gt;          text-align: center;&lt;br /&gt;                        overflow: hidden;&lt;br /&gt;                        font-weight: bold;&lt;br /&gt;                        font-size: 14px;&lt;br /&gt;      }&lt;br /&gt;      #lastUpdate&lt;br /&gt;      {&lt;br /&gt;          width: 128px;&lt;br /&gt;                        top: 20px;&lt;br /&gt;          text-align: center;&lt;br /&gt;                        overflow: hidden;&lt;br /&gt;&lt;br /&gt;                        font-size: 9px;&lt;br /&gt;      }&lt;br /&gt;     &amp;lt;/style&amp;gt;&lt;br /&gt;     &amp;lt;script type="text/javascript" src="SiteMeter.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;     &amp;lt;script type="text/jscript" language="jscript"&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        // --------------------------------------------------------------------&lt;br /&gt;        // Initialize the gadget.&lt;br /&gt;        // --------------------------------------------------------------------&lt;br /&gt;     function init()&lt;br /&gt;     {&lt;br /&gt;         var oBackground = document.getElementById("imgBackground");&lt;br /&gt;         oBackground.src = "url(images/background.png)";&lt;br /&gt;                getData();&lt;br /&gt;        }&lt;br /&gt;     &amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;/head&amp;gt;&lt;br /&gt; &lt;br /&gt;&amp;lt;body onload="init()"&amp;gt;&lt;br /&gt;    &amp;lt;g:background id="imgBackground"&amp;gt;&lt;br /&gt; &amp;lt;span id="gadgetContent"&amp;gt;-&amp;lt;/span&amp;gt;&lt;br /&gt; &amp;lt;span id="lastUpdate"&amp;gt;-&amp;lt;/span&amp;gt;&lt;br /&gt; &amp;lt;/g:background&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;SiteMeter.js&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;var globalURL = "http://www.sitemeter.com/default.asp?a=stats&amp;s=s451qaz2wsx";              // URL for lookup&lt;br /&gt;var globalTimeoutId;&lt;br /&gt;var globalError;&lt;br /&gt;var XMLHttp;&lt;br /&gt;&lt;br /&gt;function getData()&lt;br /&gt;{&lt;br /&gt;    try &lt;br /&gt;        { XMLHttp = new ActiveXObject("Msxml2.XMLHTTP"); &lt;br /&gt;    } &lt;br /&gt;    catch (e) &lt;br /&gt;        { XMLHttp = new ActiveXObject("Microsoft.XMLHTTP"); &lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // Timeout, if call not come back in 30 seconds, abort with the default error message.&lt;br /&gt;    globalTimeoutId = setTimeout(function() {&lt;br /&gt;                                         XMLHttp.abort();&lt;br /&gt;                                         document.getElementById("gadgetContent").innerHTML = "Timeout";&lt;br /&gt;                                         }, 30000); &lt;br /&gt;        &lt;br /&gt;    // Asynchronous get&lt;br /&gt;    XMLHttp.open("GET", globalURL, true);&lt;br /&gt;&lt;br /&gt;    XMLHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");&lt;br /&gt;    XMLHttp.setRequestHeader("Connection", "close");&lt;br /&gt;&lt;br /&gt;    // Callback for when the page has loaded&lt;br /&gt;    XMLHttp.onreadystatechange = parseData&lt;br /&gt;&lt;br /&gt;    // Send the request&lt;br /&gt;    XMLHttp.send(null);&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function parseData()&lt;br /&gt;{&lt;br /&gt;    var Results;&lt;br /&gt;    var td;&lt;br /&gt;&lt;br /&gt;    gadgetContent.innerHTML = XMLHttp.status;&lt;br /&gt;&lt;br /&gt;    if (XMLHttp.readyState == 4 &amp;&amp; XMLHttp.status == 200)&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;        var date = new Date();&lt;br /&gt;        lastUpdate.innerHTML = date.getDate() + "/" + (date.getMonth() +1)  + "/" + date.getYear() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();&lt;br /&gt;&lt;br /&gt;        globalError = 0;&lt;br /&gt;&lt;br /&gt;        Results = XMLHttp.responsetext;&lt;br /&gt;        if (Results.indexOf("Today") &amp;gt;= 0)&lt;br /&gt;        {&lt;br /&gt;&lt;br /&gt;            td = Results.substring(Results.indexOf("Today")+20, Results.indexOf("Today")+80);&lt;br /&gt;            td = td.substring(td.indexOf("&amp;lt;font"), td.length);&lt;br /&gt;            td = td.substring(0, td.indexOf("&amp;lt;/font&amp;gt;")+7);&lt;br /&gt;&lt;br /&gt;            gadgetContent.innerHTML = td;&lt;br /&gt;        }&lt;br /&gt;        else&lt;br /&gt;        {   &lt;br /&gt;            globalError = 1;&lt;br /&gt;            document.getElementById("gadgetContent").innerHTML = "Error";&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        // Set a callback for the getData function in one hour&lt;br /&gt;        clearTimeout(globalTimeoutId);&lt;br /&gt;        globalTimeoutId = setTimeout(getData, 3600000);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;} &lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3176205461370753084?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3176205461370753084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3176205461370753084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3176205461370753084'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/03/vista-sidebar-gadget-for-sitemeter.html' title='Vista Sidebar Gadget for SiteMeter'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_ErSjACRvSfI/Sa-_O_cH_bI/AAAAAAAAEY0/qciEB36wG68/s72-c/Background.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3055593846402824709</id><published>2009-02-24T22:28:00.002+10:00</published><updated>2009-02-24T22:33:00.039+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='NTFS'/><title type='text'>Security with 2003 R2 FSRM quotas</title><content type='html'>This post provides information on several aspects of security with Windows Server 2003 R2 FSRM quotas, which you may come across if you use the previous two posts to implement FSRM quotas on a standalone server or MSCS clustered node.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;LocalService Command Notification Task &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;If your quota has a notification task that runs a command, you may need to set the security of the executable or areas accessed by the command. By default, FSRM runs commands as the LocalService account - an account with restricted local permissions.&lt;br /&gt;&lt;br /&gt;In this example, the command executed is the logentry.bat batch file from the previous post, which simply writes a log entry to a file. To allow the batch file to run as the localservice account – which is a member of the 'Authenticated Users' group, I set the following permissions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Add authenticated users:R to the root (not OICI - object inherit, container inherit) using SDDL with cacls &lt;/li&gt;&lt;li&gt;Add authenticated users:R to c:\scripts to execute the logentry.bat file &lt;/li&gt;&lt;li&gt;Add authenticated users:C to c:\logs to allow writing the log entry &lt;/li&gt;&lt;li&gt;Ensure that cmd.exe can be executed (default permissions should suffice) &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This was done with the following commands: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;cacls c:\ /S:"D:PAI(A;OICI;FA;;;BA)(A;;0x1200a9;;;AU)(A;OICI;FA;;;SY)" &lt;/li&gt;&lt;li&gt;cacls c:\scripts /e /g "authenticated users":R &lt;/li&gt;&lt;li&gt;cacls c:\logs /e /g "authenticated users":C &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Note that while testing this, I was using localsystem (unrestricted local permissions) to verify that security was the issue, but in an MSCS cluster when failing over the virtual server from one cluster node to the other, the quota template reset itself to localservice instead of localsystem.&lt;br /&gt;&lt;br /&gt;Before setting permissions to allow LocalService to run the script, this left the notification task not executing successfully. Depending upon what your command does you may require elevated local or remote privilege, for which you may want to use localsystem or networkservice.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Target Permissions preventing execution&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;When specifying a command to run as a notification task, 2003 R2 FSRM will not allow running a command which standard users have change/full control to, directly or through inheritance.&lt;br /&gt;&lt;br /&gt;To me this seems like an unusual approach for an out of the box Microsoft product and isn't very intuitive, as in my lab inherited permissions from a parent directory allowing Users:F were causing the task to fail.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;Implementing 2003 FSRM quotas Command-line&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2009/02/implementing-2003-fsrm-quotas.html"&gt;http://waynes-world-it.blogspot.com/2009/02/implementing-2003-fsrm-quotas.html&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;2003 FSRM and NTFS Quotas compared&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2009/02/2003-fsrm-and-ntfs-quotas-compared.html"&gt;http://waynes-world-it.blogspot.com/2009/02/2003-fsrm-and-ntfs-quotas-compared.html&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;LocalService Account&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms684188(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms684188(VS.85).aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3055593846402824709?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3055593846402824709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3055593846402824709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3055593846402824709'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/02/security-with-2003-r2-fsrm-quotas.html' title='Security with 2003 R2 FSRM quotas'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8416962377696855249</id><published>2009-02-10T13:43:00.023+10:00</published><updated>2009-02-10T13:52:48.481+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='NTFS'/><title type='text'>Implementing 2003 FSRM quotas</title><content type='html'>This post provides information on implementing Windows Server 2003 FSRM quotas using the command-line dirquota.exe utility, creating a template and then applying that template to the filesystem using an autoquota. Example control files are provided to create the template, and a simple batch file to create a daily log file with quota notifications.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;The first command below creates the soft 100MB quota template with three thresholds (85/99/150), and four notifications for those thresholds, two for email and one each for and command execution and event log entry. The second command creates an autoquota using the template on the specified remote server against the specified path. Note that in this example, the commands were run on a 64-bit physical server running MSCS, and the target server was a virtual cluster server (v01).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;dirquota template add /Remote:v01 /Template:Test_Quota /Limit:100mb /type:Soft /label:"Test Default Quota" /add-threshold:85 /add-notification:85,M,c:\admin\control\Test_Quota_Email.txt /add-threshold:99 /add-notification:99,M,c:\admin\control\Test_Quota_Email.txt /add-notification:99,C,c:\admin\control\Test_Quota_Command.txt /add-notification:99,E,c:\admin\control\Test_Quota_Event.txt /add-threshold:150 /add-notification:150,M,c:\admin\control\Test_Quota_Email.txt&lt;/li&gt;&lt;li&gt;dirquota autoquota add /Remote:v01 /path:q:\folder1 /sourcetemplate:"Test_Quota"&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Notes:&lt;/div&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The use of 99% instead of 100% was intentional, as 100% is not a notification; it’s a limit, so the pre-defined variables are different. This is obvious in the subject of the email, where the ‘[Quota Threshold]’ variable isn’t resolved when it’s a 100% 'notification'.&lt;/li&gt;&lt;li&gt;The quota information is logged to \\p01\c$\logs\QuotaUsage_YYYYMMDD.log for 99% of quota usage, as well as sending an email to DiskUsageMonitor and logging an event on the cluster, and all quota information is available through the FSRM MMC snap-in.&lt;/li&gt;&lt;li&gt;Within a single email notification, an email can be sent to one or more administrators, and/or the person who took the limit over the threshold – the owner of the file. In the template below, emails will be sent to both users for all three thresholds, and administrators for the 150% notification. E-mail notifications will be limited to one per day for the same notification.&lt;/li&gt;&lt;li&gt;Any command can be run; in the example here a simple batch file is run that appends a log entry to a daily log file, providing an easy method to see quota alerts for each day.&lt;/li&gt;&lt;li&gt;The notifications aren’t triggered until first create, so if you apply quotas to existing data, the notifications won’t start appearing until new data is written.&lt;/li&gt;&lt;li&gt;A quirk with the 64-bit OS - creating the quota template only works with the 32-bit version of the dirquota.exe utility. If the physical server (p01 in the example above) were a 64-bit server, you would have to run the 32-bit dirquota.exe utility to create the template and autoquota (2003 enterprise R2 x64 SP1).&lt;/li&gt;&lt;/ol&gt;&lt;strong&gt;Configuration Files&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Templates, quotas and autoquotas can all be created via command-line utilities. When creating templates with notifications, the information is supplied via control files. Example control files for running a command, logging an event, and sending an email are shown below.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;Note the following global properties can be specified in each notification:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Notification – m | e | c | r&lt;/li&gt;&lt;li&gt;m - an e-mail notification&lt;/li&gt;&lt;li&gt;e - an event log notification&lt;/li&gt;&lt;li&gt;c - a command or script execution&lt;/li&gt;&lt;li&gt;r - a report generation&lt;/li&gt;&lt;li&gt;RunLimitInterval – The number of minutes to wait between sending notifications to save repeated unnecessary notifications. A setting of 0 indicates a notification will be sent on each trigger.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;Test_Quota_Command.txt&lt;br /&gt;&lt;br /&gt;Notification=c&lt;br /&gt;Command=c:\windows\system32\cmd.exe&lt;br /&gt;Arguments=/c c:\admin\scripts\logentry.bat "%Date%,%Time%,[Source Io Owner],[Quota Path],[Server],[Quota Limit MB] MB,[Quota Used MB] MB,[Quota Used Percent]"&lt;br /&gt;MonitorCommand=Disable&lt;br /&gt;Account=LocalService&lt;br /&gt;LogResult=Enable&lt;br /&gt;RunLimitInterval=0&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;Test_Quota_Event.txt&lt;br /&gt;&lt;br /&gt;Notification=e&lt;br /&gt;RunLimitInterval=1440&lt;br /&gt;EventType=Warning&lt;br /&gt;Message=Excessive usage by [Source Io Owner] on [Quota Path], shared on [Server]. Limit of [Quota Limit MB] MB, [Quota Used MB] MB in use ([Quota Used Percent]% of limit).&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;Test_Quota_Email.txt&lt;br /&gt;&lt;br /&gt;Notification=m&lt;br /&gt;RunLimitInterval=1440&lt;br /&gt;To=[Source Io Owner Email]&lt;br /&gt;From=FSRM@server.domain.com&lt;br /&gt;ReplyTo=FSRM-DoNotReply@server.domain.com&lt;br /&gt;Cc=DiskUsageMonitor@domain.com&lt;br /&gt;Subject=[Quota Threshold]% quota threshold exceeded&lt;br /&gt;Message=A file written by [Source Io Owner] has exceeded the [Quota Threshold]% quota threshold for the quota on [Quota Path] on server [Server]. \&lt;br /&gt;\&lt;br /&gt;The quota limit is [Quota Limit MB] MB, and [Quota Used MB] MB currently is in use ([Quota Used Percent]% of limit).\&lt;br /&gt;\&lt;br /&gt;\&lt;br /&gt;\&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;strong&gt;Logging to File&lt;/strong&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;I'm not sure why a method to append to a log file wasn't included in the GUI, but this batch file appends a one-line entry to a rolling log file:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class="mycode"&gt;&lt;code&gt;&lt;br /&gt;:: LogEntry.bat&lt;br /&gt;&lt;br /&gt;:: Write a log for quota alerts&lt;br /&gt;&lt;br /&gt;::%Date%,%Time%,[Source Io Owner],[Quota Path],[Server],[Quota Limit MB] MB,[Quota Used MB] MB,[Quota Used Percent]%&lt;br /&gt;&lt;br /&gt;Set AdminLog=C:\Logs&lt;br /&gt;&lt;br /&gt;for /f "tokens=1-8 delims=/:. " %%i in ('echo %date%') do Set DateFlat=%%l%%k%%j&lt;br /&gt;Set LogFile=%AdminLog%\QuotaUsage_%DateFlat%.log&lt;br /&gt;&lt;br /&gt;Echo %~1 &amp;gt;&amp;gt; %LogFile%&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-size: 85%;"&gt;&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;2003 FSRM and NTFS Quotas compared&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2009/02/2003-fsrm-and-ntfs-quotas-compared.html"&gt;http://waynes-world-it.blogspot.com/2009/02/2003-fsrm-and-ntfs-quotas-compared.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;FSRM and NTFS Quotas in 2003 R2&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/06/fsrm-and-ntfs-quotas-in-2003-r2.html"&gt;http://waynes-world-it.blogspot.com/2008/06/fsrm-and-ntfs-quotas-in-2003-r2.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Configuration files for notifications in File Server Resource Manager&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/a4426339-5345-44d5-81b7-a35a703daaac1033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/a4426339-5345-44d5-81b7-a35a703daaac1033.mspx?mfr=true&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;How to use File Server Resource Manager (FSRM) to configure the notification feature for File Screening Management in Windows Server 2003 R2&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/926092"&gt;http://support.microsoft.com/kb/926092&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;File Server Resource Manager Protocol Specification&lt;br /&gt;&lt;a href="http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-FSRM%5D.pdf"&gt;http://download.microsoft.com/download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-FSRM%5D.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dirquota admin options&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/14c2a340-54cf-46fa-8b0d-beed6c220c671033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/14c2a340-54cf-46fa-8b0d-beed6c220c671033.mspx?mfr=true&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;LocalService Account&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms684188(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms684188(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Configuration files for notifications in File Server Resource Manager&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/a4426339-5345-44d5-81b7-a35a703daaac1033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/a4426339-5345-44d5-81b7-a35a703daaac1033.mspx?mfr=true&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Create an auto quota&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/WindowsServer/en/library/0de5535e-ef25-4ffa-a724-155573044ddc1033.mspx"&gt;http://technet2.microsoft.com/WindowsServer/en/library/0de5535e-ef25-4ffa-a724-155573044ddc1033.mspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dirquota autoquota&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/WindowsServer2008/en/library/2809c575-8d93-47cb-8bfc-a427da83cc2a1033.mspx"&gt;http://technet2.microsoft.com/WindowsServer2008/en/library/2809c575-8d93-47cb-8bfc-a427da83cc2a1033.mspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;File Services&lt;/div&gt;&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/6e5bb377-db25-4603-b1ff-ecc4f6c29b691033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/6e5bb377-db25-4603-b1ff-ecc4f6c29b691033.mspx?mfr=true&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8416962377696855249?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8416962377696855249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8416962377696855249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8416962377696855249'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/02/implementing-2003-fsrm-quotas.html' title='Implementing 2003 FSRM quotas'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-1826231487218874018</id><published>2009-02-09T13:48:00.003+10:00</published><updated>2009-02-09T14:17:39.634+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='NTFS'/><title type='text'>2003 FSRM and NTFS Quotas compared</title><content type='html'>This post provides a quick comparison of 2003 FSRM and NTFS quotas, which I find useful when explaining how quotas in 2003 R2 work, as opposed to (or combined with) NTFS quotas.  Also included is information on where the quota data is stored, and some methods to view that data.&lt;br /&gt;&lt;br /&gt;Quota metafile information has been part of the NT filesystem since Windows NT 3.5, but has not been supported by the Operating System since the implementation of NTFS 5.0 – available in Windows 2000 and later.&lt;br /&gt;&lt;br /&gt;When enabled, NTFS quotas track information as part of each write operation to the filesystem, providing a per-volume mapping between user SID and logical disk usage based on file ownership. While all the necessary information is stored in the NT filesystem, managing NTFS quotas is time-consuming and challenging for administrators.&lt;br /&gt;&lt;br /&gt;Windows Server 2003 R2 File System Resource Manager (FSRM) provides a filesystem minifilter to control quotas, and a much improved interface to manage and report on quotas from a per-folder perspective.&lt;br /&gt;&lt;br /&gt;The main differences between the two distinct quota methods available in 2003 R2 are that:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;FSRM provides per-folder quotas, as opposed to per-user/volume NTFS quotas. Regardless of file ownership, files in a folder will count towards the FSRM-set limits. &lt;/li&gt;&lt;li&gt;SMB calls to return the free disk space are based on hard quotas at the root of the share or volume, not the quota applied to a folder - regardless of the share access point. NTFS hard quotas are volume-wide, and disk space is presented based on used-hard quota total, regardless of the share root or access method (remote SMB or local). &lt;/li&gt;&lt;li&gt;FSRM quotas count only the size on disk of files, as opposed to NTFS quotas which count the logical uncompressed size. This is primarily considered for NTFS compressed files, but is presumably the same for offline files. &lt;/li&gt;&lt;li&gt;FSRM quotas are controlled by a file system mini-filter storing quota data in \System Volume Information\SRM\quota.md and quota.xml, as opposed to NTFS quotas which are stored as part of the filesystem in \$Extend\$Quota file in $INDEX_ROOT NTFS attributes &lt;/li&gt;&lt;li&gt;FSRM allows autoquota's, a concept of setting a quota at a top-level directory and each direct child subdirectory automatically inherits a copy of that quota. This provides an easy method of exception-based quotas. Managing NTFS quotas is GUI-based unless the WMI automation interface is used and an NTFS quota entry is automatically created for each new user SID. &lt;/li&gt;&lt;li&gt;FSRM provides much improved reporting and alerting for quotas, whereas NTFS quotas only provide rudimentary reporting and eventlog entry alerting. &lt;/li&gt;&lt;li&gt;FSRM has no supported automation interface to manage quotas, whereas NTFS quotas can be managed by WMI. However, the .Net assembly srmlib.dll provides an undocumented framework for managing FSRM quotas, which could be scripted through PowerShell if required. &lt;/li&gt;&lt;li&gt;FSRM provides very strong support for command-line administration with dirquota.exe, with NTFS quotas having limited support available through fsutil &lt;/li&gt;&lt;li&gt;In a MSCS cluster scenario, FSRM stores settings in the registry, located in HKLM\Cluster\SRM\Settings\SrmGlobalSettings\Data. NTFS quotas have all information stored on the filesystem, making both methods functional in a MSCS server cluster with shared storage. &lt;/li&gt;&lt;li&gt;FSRM quotas provide improved notification - including in-built email, event logging, running a command or triggering a report. &lt;/li&gt;&lt;li&gt;FSRM quotas allow for templates to be created, separating the creation of a standard set of quotas from the application of those quotas. This allows scalability and much improved process control. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;How FSRM quota information is stored&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;FSRM quotas are stored in the "?:\System Volume Information\SRM\quota.xml" and "?:\System Volume Information\SRM\quota.sd" files, with the XML containing the configuration, and the SD file containing the actual quota information.&lt;br /&gt;&lt;br /&gt;To see the configuration of FSRM quotas for a particular volume: &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;• psexec /s /i /d cmd.exe&lt;br /&gt;• xcopy /h "?:\System Volume Information\SRM\quota.xml" %temp%&lt;br /&gt;• attrib -r -s -h "%temp%\quota.xml"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The SD file is secured so only system can access, is marked as system/hidden and is locked by the mini-filter. One method to view the SD: &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;• psexec /s /i /d cmd.exe&lt;br /&gt;• nfi "h:\System Volume Information\SRM\quota.md"&lt;br /&gt;• diskedit Read Sectors (as returned by nfi)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;How NTFS quota information is stored&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;NTFS stores quota information in a metafile on each volume called \$Extend\$Quota, with the information contained in the INDEX_ROOT $O and $Q NTFS attributes. Nfi.exe and diskedit.exe can be used to identify the file, and view the data contained in the logical sectors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;nfi q:&lt;br /&gt;&lt;br /&gt;File 24&lt;br /&gt;\$Extend\$Quota&lt;br /&gt;$STANDARD_INFORMATION (resident)&lt;br /&gt;$FILE_NAME (resident)&lt;br /&gt;$INDEX_ROOT $O (resident)&lt;br /&gt;$INDEX_ROOT $Q (resident)&lt;br /&gt;$INDEX_ALLOCATION $Q (nonresident)&lt;br /&gt;logical sectors 1036140-1036147 (0xfcf6c-0xfcf73)&lt;br /&gt;$BITMAP $Q (resident)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Quota Minifilter driver &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;FSRM quotas use a minifilter driver to function – quota.sys – mounted by default in the I/O stack with an altitude of 125000 as part of the ‘FSFilter Physical Quota Management’ group. While this altitude can be changed by modifying a registry value, this is not recommended.&lt;br /&gt;&lt;br /&gt;Both the R2 file screen filter (260800) and the cluster file system (200000-209999) are loaded higher in the stack then the quota minifilter.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;fltmc filters &amp;amp; fltmc instances&lt;br /&gt;&lt;br /&gt;Filter Name Num Instances Frame&lt;br /&gt;------------------------------ ------------- -----&lt;br /&gt;DfsDriver &lt;legacy&gt;&lt;br /&gt;Datascrn 0 0&lt;br /&gt;Quota 1 0&lt;br /&gt;&lt;br /&gt;Filter Volume Name Altitude Instance Name&lt;br /&gt;----------------------------- ----------------------------- &lt;br /&gt;Quota Q: 125000 Quota&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;To detach the filter from a volume, the following command can be run:&lt;br /&gt;• fltmc detach [volume:]&lt;br /&gt;&lt;br /&gt;Note that doing so leaves the SRM directory in the ‘System Volume Information’ on the volume, and during testing when fltmc was used to reattach the quota filter to the volume, the previous quotas were seen as invalid and returned errors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;References&lt;br /&gt;&lt;br /&gt;FSRM and NTFS Quotas in 2003 R2&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/06/fsrm-and-ntfs-quotas-in-2003-r2.html"&gt;http://waynes-world-it.blogspot.com/2008/06/fsrm-and-ntfs-quotas-in-2003-r2.html&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Inside Win2K NTFS, Part 1&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms995846.aspx"&gt;http://msdn.microsoft.com/en-us/library/ms995846.aspx&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;You cannot create quotas on File Server Resource Manager (FSRM) in Windows Server 2003 R2&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/555941"&gt;http://support.microsoft.com/kb/555941&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;FSRM quota information does not appear in the NTFS file system Quota Entries window, and NTFS file system disk quota information does not appear in FSRM in Windows Server 2003 R2&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/915042"&gt;http://support.microsoft.com/kb/915042&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Limited Group Policy management for NTFS quotas.&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/2d82decb-6726-4c5c-b872-1658b0fc3e3e1033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver/en/library/2d82decb-6726-4c5c-b872-1658b0fc3e3e1033.mspx?mfr=true&lt;/a&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Disk Quotas Tools and Settings&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/3b5b242b-7bb2-48e4-8e5f-224a08b36b271033.mspx"&gt;http://technet2.microsoft.com/windowsserver/en/library/3b5b242b-7bb2-48e4-8e5f-224a08b36b271033.mspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;HOW TO: Configure Disk Quotas for a Shared Disk in a Cluster&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/278365"&gt;http://support.microsoft.com/kb/278365&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Disk Quotas Tools and Settings&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/3b5b242b-7bb2-48e4-8e5f-224a08b36b271033.mspx"&gt;http://technet2.microsoft.com/windowsserver/en/library/3b5b242b-7bb2-48e4-8e5f-224a08b36b271033.mspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Managing Disk Quotas in Windows Server 2003 and Windows XP&lt;br /&gt;&lt;a href="http://www.microsoft.com/technet/scriptcenter/topics/win2003/quotas.mspx"&gt;http://www.microsoft.com/technet/scriptcenter/topics/win2003/quotas.mspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Designing a Disk Quota Strategy&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/1EE8754E-48D6-4472-9B53-29E8D1DE09F81033.mspx"&gt;http://technet2.microsoft.com/windowsserver/en/library/1EE8754E-48D6-4472-9B53-29E8D1DE09F81033.mspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Quotas in a cluster:&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/278365"&gt;http://support.microsoft.com/kb/278365&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;How Disk Quotas Work&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/5becbcd6-8da3-4c3b-bc0e-258acd3ec1811033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver/en/library/5becbcd6-8da3-4c3b-bc0e-258acd3ec1811033.mspx?mfr=true&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Disk Quotas and Free Space&lt;br /&gt;&lt;a href="http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/core/fncd_str_ctkj.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/core/fncd_str_ctkj.mspx?mfr=true&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Quota Minifilter Driver&lt;br /&gt;&lt;a href="http://technet2.microsoft.com/windowsserver2008/en/library/7c5a0b98-d963-4a1d-a499-316322746a8e1033.mspx?mfr=true"&gt;http://technet2.microsoft.com/windowsserver2008/en/library/7c5a0b98-d963-4a1d-a499-316322746a8e1033.mspx?mfr=true&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;MUP Changes in Microsoft Windows Vista&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/aa488427.aspx"&gt;http://msdn.microsoft.com/en-us/library/aa488427.aspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;File System Minifilter Load Order Groups and Altitude Ranges&lt;br /&gt;&lt;a href="http://www.microsoft.com/whdc/driver/filterdrv/alt-range.mspx"&gt;http://www.microsoft.com/whdc/driver/filterdrv/alt-range.mspx&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-1826231487218874018?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=1826231487218874018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1826231487218874018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1826231487218874018'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/02/2003-fsrm-and-ntfs-quotas-compared.html' title='2003 FSRM and NTFS Quotas compared'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-5896502935988854412</id><published>2009-01-30T11:35:00.003+10:00</published><updated>2009-01-30T11:44:38.727+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Cluster'/><category scheme='http://www.blogger.com/atom/ns#' term='Printing'/><category scheme='http://www.blogger.com/atom/ns#' term='Active Directory'/><title type='text'>printQueue AD objects for 2003 Cluster</title><content type='html'>Print queue objects in AD provide a useful facility when users are trying to find printers, but with a 2003 MSCS clustered virtual print spooler, occasionally the information in AD does not reflect the current state of printers. This post describes some problems I've come across with duplicate/incorrect information and some ideas of how to automatically combat the problem.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Print Queue Objects in AD &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Print queue objects in 2003 clustering are named with the virtual print server name, but they are children off a physical computer account. Which computer account the printers are children of is determined by the physical node that owned the cluster spooler resource when the printer was originally published in AD. As a virtual print server fails between nodes, the printer objects in the directory are not re-published (I assume unless the object is not found in the directory).&lt;br /&gt;&lt;br /&gt;It's intuitive that print queue objects would be republished on failover to the node that currently owns the spooler, but that could potentially be hundreds or thousands of printer objects being created/deleted with each failover so it's practical not to. It appears the printer object is confirmed using the virtual print server name, and no change is made if the object is found - regardless of which physical node the print queue object is a child of.&lt;br /&gt;&lt;br /&gt;In the scenario of a stand-alone printer server, when a printer is deleted, the spoolsv service also removes the directory object. In a clustered virtual print server this also occurs, however, it appears that in a 2003 cluster the object is not automatically removed from the directory if the node that owns the object when deleted is different than the publishing node.&lt;br /&gt;&lt;br /&gt;None of this really matters if everything is working perfectly, but in a 2003 MSCS I have seen the following situations:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Print queues that no longer exist still being visible through a search in AD &lt;/li&gt;&lt;li&gt;Duplicate print queue objects, published against each physical none in the cluster that has hosted the virtual print spooler. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The first was a bigger problem, and I believe the following scenario will result in stale print queue objects persisting: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;You have a two node cluster, CL01 and CL02. CL01 owns a virtual print spooler and other cluster groups, under which you create all the print queues. &lt;/li&gt;&lt;li&gt;At a later time you decide that the load could be better split, and move the virtual print spooler to CL02 &lt;/li&gt;&lt;li&gt;You then clean up your print queues from the virtual server, also expecting that they will be automatically removed from AD. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In the scenario above, the print queue objects would not be removed from AD, as the physical node that owns the spooler (CL02) does not own the original print queue objects - as they were created when CL01 owned the resources. In this state, the invalid print queue objects will not be purged. Note that this is assuming you aren't using AD printer pruning - by disabling the spooler service on your DCs or using Group Policy to control pruning.&lt;br /&gt;&lt;br /&gt;I'm unsure of the exact scenario that caused the duplicate print queue objects, presumably there was some problem finding the existing record, so at some point it was created off the other node as well - resulting in duplicate results in a search (both of which would work, but still).&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Some low maintenance ideas to correct this problem: &lt;/em&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Use AD printer pruning, which will ensure print queue objects in AD are managed. Note that this sounds like the obvious solution, but does have caveats and may not suit all environments. &lt;/li&gt;&lt;li&gt;Periodically remove published records from all but the designated primary node, toggle the published attribute on those printers no longer having a record in AD, causing the printers to be republished against the primary node. This could easily be scripted and scheduled &lt;/li&gt;&lt;li&gt;Modify printer creation change control processes to ensure that new printers are only created and deleted when the preferred owner is hosting the virtual print server &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In an ideal world, three above followed by one make the most sense, but if you needed option two you could do something like this: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsrm CN=%virtual_server%-%QueueName%,CN=%physical_server%,DC=domainRoot &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript prncfg.vbs -s -b \\%virtual_server%\%QueueName% -published &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript prncfg.vbs -s -b \\%virtual_server%\%QueueName% +published &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsquery * -limit 0 -filter "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -attr cn printerName distinguishedname  find /i "%QueueName%"&lt;/span&gt; &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This removes the AD object against the 'incorrect' node, toggles the published flag (using prncfg from the Resource Kit Tools - see 'Network Printing Tools and Settings' reference below), and then queries AD to verify the printQueue object has been created.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Printer Pruning in AD&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Pruning of printer objects in Active Directory is controlled either by the server that deletes the printer from its local spooler, or Domain Controllers through periodic printer pruning. Printer pruning is a domain/site-wide activity which processes all printQueue objects.&lt;br /&gt;&lt;br /&gt;In a clustered solution, I believe when a Domain Controller looks up the printqueue objects, it will connect to the virtual print spooler node to verify the printers still exist. So regardless of which physical is publishing the printer, as long as the printer is contactable through the virtual server it shouldn’t be pruned.&lt;br /&gt;&lt;br /&gt;As long as the spooler service is enabled on at least one Domain Controller, it will prune printers (at the default of 3x8 hour checks). There are risks of doing this, primarily that if the print server is down for longer than 24 hours (or if the DC can’t contact the server), all printers will be pruned from the directory. This logs an Event 50 for each pruned printer in the system event log of the DC that pruned the object - at least it’s easy to trace.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Printer Commands &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Query and compare the printers published from each server to determine duplicates:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsquery * "CN=%physical_server%,DC=domainRoot" -limit 0 -filter "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -attr cn printerName driverName printCollate printColor printLanguage printSpooling driverVersion printStaplingSupported printMemory printRate printRateUnit printMediaReady printDuplexSupported &gt; CL1.txt &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsquery * "CN=%physical_server%,DC=domainRoot" -limit 0 -filter "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -attr cn printerName driverName printCollate printColor printLanguage printSpooling driverVersion printStaplingSupported printMemory printRate printRateUnit printMediaReady printDuplexSupported &gt; CL2.txt &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1" %i in (CL1.txt) do @find /i "%i" CL2.txt&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The following two commands help identify mismatches in printers published in AD versus those shared through the virtual print server.&lt;br /&gt;&lt;br /&gt;Count the number of printers published in AD: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;find /i /c "%virtual_server%" CL?.txt &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The number of printers shared against a node: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;rmtshare \\%physical_server% find /i "\\%virtual_Server%" /c &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Query printers published against a physical server:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsquery * "CN=%physical_server%,DC=domainRoot" -limit 0 -filter "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -attr cn printerName driverName printCollate printColor printLanguage printSpooling driverVersion printStaplingSupported printMemory printRate printRateUnit printMediaReady printDuplexSupported&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;References:&lt;br /&gt;&lt;br /&gt;Network Printing Tools and Settings&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet.microsoft.com/en-us/library/cc778201.aspx"&gt;&lt;span style="font-size:85%;"&gt;http://technet.microsoft.com/en-us/library/cc778201.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Printer Pruner May Prune All the Print Queue Objects on Its Site&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/246906"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/246906&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Printer Pruner May Not Remove Printer Queue Objects from Active Directory&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/246174/"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/246174/&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;A server does not prune printers on a Microsoft Windows Server 2003-based server cluster&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/908128"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/908128&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Useful Windows Printer command-line operations:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-5896502935988854412?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=5896502935988854412' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5896502935988854412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5896502935988854412'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/01/printqueue-ad-objects-for-2003-cluster.html' title='printQueue AD objects for 2003 Cluster'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3994172015926350000</id><published>2009-01-19T21:06:00.003+10:00</published><updated>2009-01-19T21:34:44.976+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>VirtualCenter Physical to Virtual</title><content type='html'>This post describes a process I executed to replace a physical VMware VirtualCenter box with a virtual equivalent running in its own cluster. There were no VM outages of machines running on the cluster – each ESX kept merrily running the virtuals until everything was sorted out with the VC layer.&lt;br /&gt;&lt;br /&gt;Note that this was done in a lab instance of ESX 3.5 and VirtualCenter 2.5, had this been production I probably would have taken a little more care.&lt;br /&gt;&lt;br /&gt;I don’t think there is any compelling reason why you wouldn’t run a virtual VC box, it would be hypocritical of VMware to suggest virtualizing your application servers, except VirtualCenter which should be physical. Having said that, this process could also be used in reverse, taking a VM VirtualCenter instance physical should the need arise. This would also be useful for a VirtualCenter disaster recovery scenario.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;The configuration before completing these steps&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Physical VirtualCenter 2.5 running on Windows Server 2003, called vc01, static IP &lt;/li&gt;&lt;li&gt;Virtual Windows Server 2003 computer running in the cluster, called vc02, dynamic IP \&lt;/li&gt;&lt;li&gt;SQL 2005 database for VC, running on a separate SQL server. &lt;/li&gt;&lt;li&gt;ESX 3.5 VC 2.5, single network, iSCSI shared storage&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The IP address of the VirtualCenter server &lt;/li&gt;&lt;li&gt;The ESX host of the VM becoming the new VC server &lt;/li&gt;&lt;li&gt;The path to your VMware FlexLM license file (assuming you’re using a license server) &lt;/li&gt;&lt;li&gt;The logon details for the SQL connection between vpxd and the database &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Steps Taken&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;On the physical VirtualCenter box that is going to be decommissioned: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Take note of the physical ESX host running the VM becoming the new VC server &lt;/li&gt;&lt;li&gt;Stop the vpxd service and change the startup to manual (sc stop %service%, sc config %service% start= demand) &lt;/li&gt;&lt;li&gt;Stop the vmountVpx, vmware-ufad-vci, vmware-converter and webAccess services change the startup to manual &lt;/li&gt;&lt;li&gt;Stop the flexlm instance and set the startup to manual &lt;/li&gt;&lt;li&gt;Take a backup of your .lic license file &lt;/li&gt;&lt;li&gt;Change the IP address to dynamic (assuming it is static) &lt;/li&gt;&lt;li&gt;Power off the physical machine &lt;/li&gt;&lt;li&gt;Delete the computer account for vc01 from the domain &lt;/li&gt;&lt;li&gt;On the SQL server hosting the VirtualCenter database, backup the VC database and log file with the following command executed through management studio:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;BACKUP DATABASE [VMVC]&lt;br /&gt;TO DISK = N'c:\temp\VC_PreMoveToVM.bak'&lt;br /&gt;WITH&lt;br /&gt;DESCRIPTION = N'VirtualCenter Pre-move to VM backup'&lt;br /&gt;, INIT&lt;br /&gt;, NAME =&lt;br /&gt;N'VC Pre move to VM'&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;RESTORE VERIFYONLY&lt;br /&gt;FROM DISK =&lt;br /&gt;N'c:\temp\VC_PreMoveToVM.bak '&lt;br /&gt;WITH FILE = 1&lt;br /&gt;GO&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;li&gt;In the service console of one of the ESX hosts, backup the current certificates (just in case):&lt;/li&gt;&lt;ol type="a"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;mkdir /tmp/cert_backup &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cp /etc/vmware/ssl/* /tmp/cert_backup&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;On the VM becoming the new VirtualCenter server running on a host in the cluster: Rename the server from vc02 to vc01, with the same static IP as the previous vc01 &lt;/li&gt;&lt;li&gt;Restart the virtual machine &lt;/li&gt;&lt;li&gt;Install the SQL Native Client - required for VC 2.5 SQL connectivity on a non-SQL server &lt;/li&gt;&lt;li&gt;Install VirtualCenter including FlexLM, connecting to the existing database and using the license file copied off the physical server &lt;/li&gt;&lt;li&gt;In VirtualCenter, disconnect the first ESX host in the cluster - maintenance mode is not possible at this stage – login errors occur because of the incorrect certificate &lt;/li&gt;&lt;li&gt;Copy the new VC certificates - I use pscp here, but whatever you normally use to copy files to ESX would be fine:&lt;br /&gt;&lt;ol type="a"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cd "C:\Documents and Settings\All Users\Application Data\VMware\VMware VirtualCenter\ssl"&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;pscp rui.crt vcadmin@esx01:/etc/vmware/ssl/&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;pscp rui.key vcadmin@esx01:/etc/vmware/ssl/"&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;In the service console of the ESX node you’ve just updated the certificates on, restart the management interface, the ESX host did not seem to pick up the new certificate dynamically (maybe it would on a schedule without a restart): &lt;ol type="a"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;service mgmt-vmware restart&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Connect the ESX host to VC through the VI Client interface &lt;/li&gt;&lt;li&gt;Repeat steps 15-18 for each other ESX host in the cluster &lt;/li&gt;&lt;li&gt;In VirtualCenter, run 'Reconfigure for HA' on each ESX node&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Testing&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Ensure the vpxd.log file reports no problems with host connectivity or certificates (also check the VC/ESX logs) &lt;/li&gt;&lt;li&gt;Ensure each ESX host is receiving licenses from the 'new' license server, either through the VI client or the FlexLM admin tool. &lt;/li&gt;&lt;li&gt;Ensure you can perform simple tasks such as powering on a virtual machine &lt;/li&gt;&lt;li&gt;Ensure VMotion/HA/DRS is working &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The (untested) rollback plan if something goes wrong: &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Shutdown the new VirtualCenter VM &lt;/li&gt;&lt;li&gt;Restore the database from the backup taken &lt;/li&gt;&lt;li&gt;Power on the physical VC box, change the IP to the static IP &lt;/li&gt;&lt;li&gt;Restart the vpxd and VMware License Server services &lt;/li&gt;&lt;li&gt;For each ESX host in the cluster, disconnect the host, restore the old certificates, restart the management service and connect the ESX host to the old VirtualCenter instance &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Additional notes: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Even though user login errors were returned when the vpxd service tried to form the cluster - which points to the vpxuser account used by VC to manage ESX hosts - this was misleading as this username and password is stored in the VC database – which had not been modified (in the vpx_host table). The next logical step was certificates, which lead to certificate update process used above. &lt;/li&gt;&lt;li&gt;Manually copying the certificates may not be strictly required, as when I went part-way to reconnecting a host without updating the certificates, I was prompted that another VC instance was managing these servers, would I like to continue. Presumably it would have automatically updated the certificates as required. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3994172015926350000?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3994172015926350000' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3994172015926350000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3994172015926350000'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/01/virtualcenter-physical-to-virtual.html' title='VirtualCenter Physical to Virtual'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-5611393971813325549</id><published>2009-01-17T09:41:00.002+10:00</published><updated>2009-01-17T10:05:17.737+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><category scheme='http://www.blogger.com/atom/ns#' term='Cluster'/><title type='text'>Virtual 2003 MSCS Cluster in ESX VI3</title><content type='html'>This post shares a method I've used to create test-lab instances of standard 2003 file and print Microsoft Cluster Services (MSCS) clusters in a VMware ESX VI3 virtual environment. The resultant solution is not supported and definitely not production-ready, but if you want a real multi-node MSCS cluster in an ESX lab environment, this process might be helpful with a minimum set of requirements.&lt;br /&gt;&lt;br /&gt;With my usual theme of repeatable command-line execution, most of these operations can be completed via the command-line, either in the ESX service console or a command-prompt from the virtual MSCS nodes.&lt;br /&gt;&lt;br /&gt;I followed bits and pieces of the VMware supported method - which is very specific and quite restrictive.  Note that I’m a little dubious that this cluster would be particularly stable – the SCSI reservations MSCS uses to lock disks are in no way supported when using a shared VMDK through a shared SCSI adapter (I think RDM is the only supported method), but it does work and at least provided me with a test environment.&lt;br /&gt;&lt;br /&gt;The shared nothing model of 2003 MSCS clustering dictates that only one node accesses the partition at any one time, but the disk still needs to be visible to both nodes. A limitation of this solution is that both MSCS nodes need to be hosted on one ESX server – a requirement you could satisfy with a DRS rule to keep the two nodes together. However, if DRS decided to migrate both VMs, the cluster would almost certainly break during the failover (and possibly after).&lt;br /&gt;&lt;br /&gt;If you follow the steps below, you should end up with two virtual x64 2003 enterprise servers, both members of a single MSCS cluster. In the cluster there will three shared disks (VMDKs), one for the quorum and one each for file and print – with a virtual server and relevant cluster resources. A test file share is created, along with drivers and a test printer.  You'll need to modify the commands that reference the public adapter and IP addresses&lt;br /&gt;&lt;br /&gt;Steps involved:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create an area for storage of the shared disk on your datastore: &lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;mkdir /vmfs/volumes/%datastore%/cluster01&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create a 5GB quorum disk:&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;vmkfstools -d thick -a lsilogic -c 5G /vmfs/volumes/%datastore%/cluster01/MSCS-Quorum.vmdk&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create a 5GB disk for shared data:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;vmkfstools -d thick -a lsilogic -c 5G /vmfs/volumes/%datastore%/cluster01/MSCS-disk01.vmdk&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create two 2003 x64 enterprise virtual machines, either through cloning, deployment with templates or whatever your standard build process may be &lt;/li&gt;&lt;li&gt;If cloning was used, run sysprep on both nodes to give a unique SID and join your lab domain &lt;/li&gt;&lt;li&gt;Shutdown the first node and add the shared disk&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;Add the quorum disk, mounted under scsi 1:0 (which adds a new SCSI adapter) &lt;/li&gt;&lt;li&gt;Set the newly created SCSI Adapter to SCSI bus sharing virtual &lt;/li&gt;&lt;li&gt;Add disk01, attached as scsi 1:1&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;In the first VM, use disk administrator (or diskpart) to initialise the quorum and disk01 disks, partitioned with basic. Record the signature of the disk and the drive letter used (although this is the disk volume when the disk is owned by the OS, not the cluster). &lt;li&gt;Add a service account for the cluster service:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsadd user "CN=clustersvc,CN=Users,DC=test,DC=local" -pwdneverexpires yes -pwd password -disabled no -desc "MSCS VM cluster service account" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;Ensure the service account is an administrator of each virtual 2003 node&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Use Cluster Administrator to install the cluster on the first node, with your chosen cluster name, using the created quorum disk and service account &lt;/li&gt;&lt;li&gt;Verify correct operation of the single-node cluster, and then add the second VM node to the cluster. &lt;/li&gt;&lt;li&gt;Create a new port group to allow a second private adapter on each ESX server:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;esxcfg-vswitch -A MSCS-Private Private &lt;/span&gt;&lt;li&gt;Add a second interface to each VM cluster node, allocated separate address space &lt;/li&gt;&lt;li&gt;Verify connectivity (ping) and configuration following cluster best practices (no gateway, no DNS etc) &lt;/li&gt;&lt;li&gt;Mark as a private heartbeat connection for the cluster, prioritised above the LAN connection.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create a virtual resource group, creating IP, network name and disk resources in the group, the following commands will create a group called v01, in the lab01 cluster. For these steps, you’ll need the drive letter to use (M: below), the disk signature, the public network name, IP Address and subnet mask of the virtual server being created:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 group "v01" /create &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Disk01" /create /group:"v01" /type:"physical disk" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Disk01" /priv Drive="M:" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Disk01" /priv signature=0x%disksignature% &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Disk01" /prop Description="M: disk01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Disk01" /On &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /create /group:"v01" /type:"IP Address" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv Network="%publicNetwork%" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv Address=192.168.10.10 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv SubnetMask=255.255.255.0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv EnableNetBIOS=1 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv OverrideAddressMatch=0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /AddDep:"v01 Disk01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /On &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01" /create /group:"v01" /type:"Network Name" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01" /priv RequireKerberos=1 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01" /AddDep:"v01 IP" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01" /priv Name="v01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01" /On&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Install ABEUIamd64.msi on each node if Access Based Enumeration is required &lt;li&gt;To create a test directory, share and ABE resource on the new virtual server on the cluster (v01):&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;md \\v01\m$\Dir01 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /create /group:"v01" /type:"File Share" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /priv path="M:\Dir01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /priv Sharename=Dir01 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /priv Remark="Dir01 File Share" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /prop Description="Dir01 File Share" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /priv security=Everyone,grant,F:security &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /AddDep:"v01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /AddDep:"v01 Disk01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 Share" /On &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /create /group:"v01" /type:"Generic Application" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /priv CommandLine="cmd.exe /k abecmd.exe /enable Dir01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /priv CurrentDirectory="%SystemRoot%" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /priv InteractWithDesktop=0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /priv UseNetworkName=0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /prop SeparateMonitor=1 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /prop Description="Access Based Enumeration for Dir01 File Share" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /AddDep:"v01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /AddDep:"v01 Disk01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /AddDep:"v01 Dir01 Share" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 Dir01 ABE" /On&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Additional shared cluster disks can be created as required, eg:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;vmkfstools -d thick -a lsilogic -c 5G /vmfs/volumes/%datastore%/cluster01/MSCS-disk02.vmdk&lt;/span&gt; &lt;/li&gt;&lt;li&gt;Add the disks to one node, (scsi 1:2 in this example). Initialise and allocate in the cluster (as in step 7 above)&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;To create a virtual print server (assuming you’ve mounted disk02 from step 15 for use in the cluster):&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 group "v02" /create &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Disk02" /create /group:"v02" /type:"physical disk" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Disk02" /priv Drive="P:" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Disk02" /priv signature=0x%disksignature% &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Disk02" /prop Description="P: print01" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Disk02" /On &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 IP" /create /group:"v02" /type:"IP Address" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv Network="%publicNetwork%" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv Address=192.168.10.11 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v01 IP" /priv SubnetMask=255.255.255.0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 IP" /priv EnableNetBIOS=1 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 IP" /priv OverrideAddressMatch=0 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 IP" /AddDep:"v02 Disk02" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 IP" /On &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02" /create /group:"v02" /type:"Network Name" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02" /priv RequireKerberos=1 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02" /AddDep:"v02 IP" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02" /priv Name="v02" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02" /On&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create v02 print spooler:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /create /group:"v02" /type:"print spooler" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /priv DefaultSpoolDirectory="P:\Spool" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /prop Description="v02 Print Spooler" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /AddDep:"v02 Disk02" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /AddDep:"v02" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cluster /cluster:lab01 res "v02 Spooler" /On&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;On v02, add a standard Laserjet 4000 retail driver for x64 and x86, run from a cluster node:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;rundll32 printui.dll,PrintUIEntry /ia /c \\v02 /m "HP LaserJet 4000 Series PCL6" /h "x64" /v "Windows XP and Windows Server 2003" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;rundll32 printui.dll,PrintUIEntry /ia /c \\v02 /m "HP LaserJet 4000 Series PCL6" /h "x86" /v "Windows 2000, Windows XP and Windows Server 2003"&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Create a test printer on v02 called printer01 using the LJ 4000 driver, with a record in DNS, published in AD, set to duplex by default, with customised permissions using the standard winprint processor:&lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dnscmd %DNSserver% /recordadd %zone% printer01 A 192.168.10.100 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript //nologo portmgr.vbs -a -c \\v02 -p printer01 -h 192.168.10.100 -t LPR -q printer01 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript //nologo prnmgr.vbs -a -c \\v02 -b printer01 -m "HP LaserJet 4000 Series PCL6" -r printer01 &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;cscript //nologo prncfg.vbs -s -b \\v02\printer01 -h printer01 -l "%Location%" +published &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;setprinter.exe \\v02\printer01 8 "pDevMode=dmDuplex=2,dmCollate=1,dmFields=duplex collate" &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;subinacl /printer \\v02\printer01 /grant=%domain%\%group%=F &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;setprinter \\v02\printer01 2 pPrintProcessor="WinPrint"&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;References&lt;/span&gt;&lt;/p&gt;&lt;span style="font-size:85%;"&gt;VMware Support method of running MSCS clusters:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;a href="http://www.vmware.com/pdf/vi3_35/esx_3/r35u2/vi3_35_25_u2_mscs.pdf"&gt;http://www.vmware.com/pdf/vi3_35/esx_3/r35u2/vi3_35_25_u2_mscs.pdf&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Implementing an MSCS 2003 server cluster Cluster&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/03/implementing-mscs-2003-server-cluster.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/03/implementing-mscs-2003-server-cluster.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;subinacl 5.2.3790.1180:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B"&gt;&lt;span style="font-size:85%;"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows Server 2003 Resource Kit Tools:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;amp;DisplayLang=en"&gt;&lt;span style="font-size:85%;"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;amp;DisplayLang=en&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-5611393971813325549?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=5611393971813325549' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5611393971813325549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/5611393971813325549'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/01/virtual-2003-mscs-cluster-in-esx-vi3.html' title='Virtual 2003 MSCS Cluster in ESX VI3'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4075872710895088431</id><published>2009-01-09T22:21:00.001+10:00</published><updated>2009-01-09T22:34:25.903+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='DNS'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Finding duplicate DNS records</title><content type='html'>Internal DNS in many organisations is usually a little messy and if tasked with cleaning it, my first step would be to identify duplicate records in DNS - either an IP address that is recorded against multiple host names or a host name with multiple host (A) records.  Assuming you have a file containing one record per line, this is fairly simple to report on.&lt;br /&gt;&lt;br /&gt;The following examples use dnscmd.exe, which assumes Windows 2000/2003 DNS, but you could use any input, as long as it contains a name and an IP.&lt;br /&gt;&lt;br /&gt;The two commands:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;ol&gt;&lt;li&gt;dnscmd %dnsServer% /enumrecords test.local @ /additional /continue &amp;#124; find /i /v "Aging:" &amp;#124; find /i "192.168" &amp;gt; DNSRecords.txt&lt;/li&gt;&lt;li&gt;echo. &amp;gt; DuplicateIPs.txt &amp; (for /f "tokens=1,4" %i in (DNSRecords.txt) do @if "%j" NEQ "" @find /i "%j" DuplicateIPs.txt &amp;gt;nul &amp; if errorlevel 1 for /f "tokens=1" %m in ('"findstr /i "%j$" DNSRecords.txt &amp;#124; find /i /c "%j""') do @if %m GTR 1 (@echo %j,%m: &amp; findstr /i "%j$" DNSRecords.txt &amp; echo.) &amp;gt;&amp;gt; DuplicateIPs.txt) &amp; type DuplicateIPs.txt&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The first command uses dnscmd to enumerate the records from the root of the test.local zone and exclude aging (dynamic DNS) records.  The last find command further filters the output by IP, which can be useful when targeting specific subnets/sites.  You might also want to check aging dynamic records instead of static to see how well scavenging is working – if you do, just change the tokens to 1,5 instead of 1,4 (as the aging data is another token separating the name and IP).&lt;br /&gt;&lt;br /&gt;The second command:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Creates a new file called DuplicateIPs.txt in the current working directory&lt;/li&gt;&lt;li&gt;Iterates through each line in the DNS record dump, extracting the first and fourth token (Name and IP)&lt;/li&gt;&lt;li&gt;The commands in the first FOR loop check there is a value, then check the value hasn't already been processed in the duplicate list (otherwise you'd have duplicates of each duplicate) and then counts the duplicates and appends them to the file.&lt;/li&gt;&lt;li&gt;The final command types the duplicate IP file created by the for loop iteration.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;For example, supposing your DNS export contained the following records:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;printer1 3600 A 192.168.10.100&lt;br /&gt;printer2 3600 A 192.168.10.101&lt;br /&gt;printer3 3600 A 192.168.10.100&lt;br /&gt;printer4 3600 A 192.168.10.102&lt;br /&gt;printer5 3600 A 192.168.10.103&lt;br /&gt;printer6 3600 A 192.168.10.100&lt;br /&gt;printer7 3600 A 192.168.10.102&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After running the second command above, a file called DuplicateIPs.txt would be created and then typed to the prompt:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;192.168.10.100,3:&lt;br /&gt;printer1 3600 A 192.168.10.100&lt;br /&gt;printer3 3600 A 192.168.10.100&lt;br /&gt;printer6 3600 A 192.168.10.100&lt;br /&gt;&lt;br /&gt;192.168.10.102,2:&lt;br /&gt;printer4 3600 A 192.168.10.102&lt;br /&gt;printer7 3600 A 192.168.10.102&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The command below is modified to report duplicate names instead of IP addresses.  This was done by using the first token (%i) instead of the second (%j), and modifying the findstr command to use a literal string search ending with a space rather than the regular expression EOL:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;echo. &amp;gt; DuplicateIPs.txt &amp; (for /f "tokens=1,4" %i in (DNSRecords.txt) do @if "%i" NEQ "" @find /i "%i" DuplicateIPs.txt &amp;gt;nul &amp; if errorlevel 1 for /f "tokens=1" %m in ('"findstr /i /c:"%i " DNSRecords.txt &amp;#124; find /i /c "%i""') do @if %m GTR 1 (@echo %i,%m: &amp; findstr /i /c:"%i " DNSRecords.txt &amp; echo.) &amp;gt;&amp;gt; DuplicateIPs.txt) &amp; type DuplicateIPs.txt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you wanted a summary rather than the detail of each duplicate, you could also run the following command:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;br /&gt;echo. &amp;gt; DuplicateIPSummary.txt &amp; (for /f "tokens=1,4" %i in (DNSRecords.txt) do @if "%j" NEQ "" @find /i "%j" DuplicateIPSummary.txt &amp;gt;nul &amp; if errorlevel 1 for /f "tokens=1" %m in ('"findstr /i "%j$" DNSRecords.txt &amp;#124; find /i /c "%j""') do @if %m GTR 1 (@echo %j,%m) &amp;gt;&amp;gt; DuplicateIPSummary.txt) &amp; type DuplicateIPSummary.txt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the example above, this would produce the following report:&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;192.168.10.100,3&lt;br /&gt;192.168.10.102,2&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I use this sort of command to generate reports on duplicates, in this case from DNS, but it could also be useful in DHCP, WINS, or any number of Active Directory objects/attributes.  People (myself included) are often wary of automated processes that make changes, but this is an excellent example of how powerful read-only automated commands can be – you can take thousands of objects and produce a report in seconds to quickly identify inconsistencies in an environment.&lt;br /&gt;&lt;br /&gt;Dnscmd Overview &lt;br /&gt;&lt;a href=http://technet.microsoft.com/en-us/library/cc778513.aspx&gt;http://technet.microsoft.com/en-us/library/cc778513.aspx&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4075872710895088431?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4075872710895088431' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4075872710895088431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4075872710895088431'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2009/01/finding-duplicate-dns-records.html' title='Finding duplicate DNS records'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8298348437205307431</id><published>2008-12-29T23:35:00.003+10:00</published><updated>2008-12-29T23:42:18.884+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Command-line automation – Echo and macros</title><content type='html'>This is the fifth and last in a series of posts containing information on what I consider the building blocks to automate repetitive tasks at the Windows command-line. These components are the for, find, findstr, set, if and echo commands, control files used to control data input, combined with errorlevels, command concatenation, nested loops and if/then/else constructs.&lt;br /&gt;&lt;br /&gt;Described in this post is the echo command and how to execute your commands using macros with doskey.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Echo&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Echo is one of the most important commands to use when constructing repeatable commands – you should never run a command against multiple objects without first using echo. Some commands can be disastrous without appropriate input checking.&lt;br /&gt;&lt;br /&gt;For example, using a wildcard incorrectly in a file spec, instead of putting *.txt, below I’ve put ‘* .txt’ – the wildcard selecting everything in the current directory (with the unfortunate del command for each of those files).&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (* .txt) do echo del %i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or more commonly – an incorrectly formed control file. The following command is one I’ve used to fix invalidly set UPNs on user accounts in the local directory. This command is quite powerful, and can be used to fix dozens or hundreds of accounts in seconds – but if the input file is not well formed, you could end up breaking each account:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1 tokens=1,2-3" %i in (NoUPN.txt) do echo dsmod user "%j %k" -upn &lt;/span&gt;&lt;a href="mailto:%i@%upnsuffix%"&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;%i@%upnsuffix%&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Incidentally, the command used to generate the ‘NoUPN.txt’ file was:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dsquery * %OU% -filter "&amp;amp;(objectclass=user)(objectcategory=person)(!(userprincipalname=*))" -s %server% -scope onelevel -attr name distinguishedname &gt; NoUPN.txt&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you are untrusting of using the ‘for /f’ to execute operations against multiple objects, you can also use echo to construct a batch file that you can run at a later time – good practice rather than writing and executing the command in a single attempt. This may also useful when you’re modifying hundreds or thousands of objects and you don’t want to execute the commands immediately – for example if the modifications were in Active Directory and you wanted to prevent excessive replication during the day.&lt;br /&gt;&lt;br /&gt;Running the command above with an appended redirect (&gt;&gt;) to a file, you could then pass this file to someone else for sanity checking before actual execution of the batch job:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1 tokens=1,2-3" %i in (NoUPN.txt) do echo dsmod user "%j %k" -upn %i@%upnsuffix% &gt;&gt; %temp%\SetUPN.bat&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Doskey macros&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In the previous post there was a command to calculate a subnet at the command-line. If you had to type it every time - or even copy and paste - it’s not something you would use (okay, you’d probably never use it anyway), but doskey macros provide a simple method of allowing command re-use.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Creating a macro file&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;A text file can be created containing your macros, choose a shorthand name for the command, followed by the command you wish to execute. One slightly odd aspect with a macro file is that variables passed at the command-line for the macro use the $ prefix instead of %.&lt;br /&gt;&lt;br /&gt;To make macros more useful, I often add two options – one without any parameters with a defined default, and another accepting a parameter to customise the command. For example, the following macro - called ‘AD2003’ - would by default query the local directory for all 2003 computer accounts. If a parameter is passed ($1), the dsquery command passes the parameter as the start node for the search (which could be a DN to limited the containers queried, or a different domain than domainroot).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;AD2003=if _$1==_ (dsquery * domainroot -filter "(&amp;amp;(objectCategory=Computer)(objectClass=Computer)(operatingSystem=Windows Server 2003))" -limit 0) else (dsquery * $1 -filter "(&amp;amp;(objectCategory=Computer)(objectClass=Computer)(operatingSystem=Windows Server 2003))" -limit 0)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The find subnet command from the previous post could be shortened to execute the command with something as simple as ‘fs 192.168.11.40 255.255.254.0’, by adding the following to a macro file (and executing on a command processor with delayed expansion enabled):&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;FS=for /f "tokens=1-8 delims=.- " %i in ('echo $1 $2') do @set /a Octet1="%i &amp;amp; %m" &gt;nul &amp;amp; @set /a Octet2="%j &amp;amp; %n" &gt;nul &amp;amp; @set /a Octet3="%k &amp;amp; %o" &gt;nul &amp;amp; @set /a Octet4="%l &amp;amp; %p" &gt;nul &amp;amp; Echo !Octet1!.!Octet2!.!Octet3!.!Octet4!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Automatically enabling the macro file&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;It would also be unwieldy if you had to enable the doskey macros each time you ran a command shell. However, you can easily automate this with the autorun key of the shell, stored in either &lt;blockquote&gt;&lt;p&gt;HKCU or HKLM:&lt;br /&gt;Key - HKEY_LOCAL_MACHINE\software\microsoft\Command Processor&lt;br /&gt;Value - AutoRun&lt;br /&gt;Value Type - REG_SZ&lt;br /&gt;Value Data - doskey /macrofile=c:\util\macros.txt (or wherever)&lt;br /&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;This concludes what hopefully was a useful description of how I use built-in shell commands to automate repetitive tasks and make my work life easier and more efficient. Some of the resultant commands are not particularly easy to follow, but each can be broken down into the component parts and digested separately.&lt;br /&gt;&lt;br /&gt;For more real-world examples of how I use the information in the last five posts, see my command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8298348437205307431?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8298348437205307431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8298348437205307431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8298348437205307431'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/command-line-automation-echo-and-macros.html' title='Command-line automation – Echo and macros'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7407876905744133091</id><published>2008-12-27T22:48:00.004+10:00</published><updated>2008-12-27T23:26:17.391+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Command-line automation – set</title><content type='html'>This is the fourth in a series of posts containing information on what I consider the building blocks to automate repetitive tasks at the Windows command-line. These components are the for, find, findstr, set, if and echo commands, control files used to control data input, combined with errorlevels, command concatenation, nested loops and if/then/else constructs.&lt;br /&gt;&lt;br /&gt;Described in this post is the ‘set’ command, which I find very useful when automating repetitive tasks with ‘for’. I use set in four ways – string manipulation, simple arithmetic operations with ‘set /a’, gathering input with ‘set /p’ or concatenating output in a single for loop with delayed variable expansion.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;String Manipulation&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;My most frequent use of the set command is simple string manipulation at the command prompt. I use this to replace one character with another or extract a substring.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Replace&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Replacing one string with another is a core function of string manipulation. Even though this is included under help for ‘set’, this functionality works for other commands, including the echo command.&lt;br /&gt;&lt;br /&gt;For example, say you have the fully qualified user DNS name – my.domain.com – and this conveniently is also the distinguished name of your AD domain, the following command replaces periods with ‘,DC=’ and prefixes an additional string to provide the distinguished name:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo DC=%userdnsdomain:.=,DC=% &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This would turn ‘my.domain.com’ into:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;DC=my,DC=domain,DC=com&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Wildcards can also be used, for example, to remove the first element, you could replace up to the first dot with nothing:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo %userdnsdomain:*.=%&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;You could also remove spaces and print the output, for example, if the ‘test’ variable contained ‘A Sentence With Spaces’, running:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo %test: =%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Would result in:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ASentenceWithSpaces &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Substrings&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;You can extract from existing variables (or inline if using delayed expansion), providing Left/Right/Mid functionality. This can be useful in many ways, but for most of the input I deal with, splitting with ‘for’ and delimiters (such as comma or space) makes for simpler processing with dynamic input. For examples sake, if you had a defined length of padded text, and you wanted the 10 characters starting at the 20th character (0-based), you could run:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo %input:~19,10%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You could also extract the last 10 characters:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo %input:~-10%&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Or all but the last 10 characters:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo %input:~0,-10%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Arithmetic operations &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;‘set /a’ supports a relatively simple but still powerful set of arithmetic, bitwise and shift operators, and while I’ve never found much use for them, upon occasion they have come in handy.&lt;br /&gt;&lt;br /&gt;For example, this command will tell you what next year will be and set the NextYear environment variable, based on the current year + 1:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3 delims=/" %i in ('echo %date%') do set /a NextYear=%i+1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Similarly, find the current month, increment by one, unless the current month is 12, then wrap around and start at 1 again:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=2 delims=/" %i in ('echo %date%') do if %i==12 (Set NextMonth=1 &amp;amp; echo !NextMonth!) else (Set /a NextMonth=%i+1)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the example above uses delayed environment variable expansion, see below for a description.&lt;br /&gt;&lt;br /&gt;Incidentally, if you were going to use this output for something and if the month were a single digit you would lose the padding, which would then be incorrectly sorted (as compared to other padded output). The example below pads the month, then extracts the last two characters, effectively padding single-digit months (see string manipulation above):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set NextMonth=0%NextMonth%&lt;br /&gt;echo %nextmonth:~-2%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An actual use I have found for the arithmetic operators is to calculate subnets from the command-line. I have made use of this when parsing netsh dhcp output (there were thousands of leases across several DHCP servers serving dozens of subnets, and I wanted to know from the leases which subnets were in use).&lt;br /&gt;&lt;br /&gt;This can be done with a single command-line, but it’s a little complicated, the batch file below may be easier to demonstrate the ‘set /a’ functionality. Running this batch file with an IP and mask, eg ‘&lt;span style="font-family:courier new;font-size:85%;"&gt;findsubnet.bat 192.168.11.40 255.255.254.0&lt;/span&gt;’ will return the subnet (192.168.10.0 in this example) using bitwise AND of the two sets of octets:&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;@Echo Off&lt;br /&gt;Set Input=%1&lt;br /&gt;Set Mask=%2&lt;br /&gt;If /i "%Input%"=="" Goto End&lt;br /&gt;&lt;br /&gt;for /f "tokens=1-8 delims=.- " %%i in ('echo %Input% %Mask%') do Call :FindOctet %%i %%j %%k %%l %%m %%n %%o %%p&lt;br /&gt;Goto End&lt;br /&gt;&lt;br /&gt;:FindOctet&lt;br /&gt;::Echo %1 %2 %3 %4 %5 %6 %7 %8&lt;br /&gt;&lt;br /&gt;set /a Octet1="%1 &amp;amp; %5" &gt;nul&lt;br /&gt;set /a Octet2="%2 &amp;amp; %6" &gt;nul&lt;br /&gt;set /a Octet3="%3 &amp;amp; %7" &gt;nul&lt;br /&gt;set /a Octet4="%4 &amp;amp; %8" &gt;nul&lt;br /&gt;Echo %1.%2.%3.%4,%Octet1%.%Octet2%.%Octet3%.%Octet4%,%5.%6.%7.%8&lt;br /&gt;Set Octet1=&lt;br /&gt;Set Octet2=&lt;br /&gt;Set Octet3=&lt;br /&gt;Set Octet4=&lt;br /&gt;Goto End&lt;br /&gt;&lt;br /&gt;:InvalidArgs&lt;br /&gt;Echo Invalid arguments, please provide an IP and longhand mask, eg 192.168.11.40 255.255.254.0&lt;br /&gt;Goto End&lt;br /&gt;&lt;br /&gt;:End&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Input&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Set can be used to gather input, making your commands or batch files interactive. For example, the following command assigns the input to the ‘test’ environment variable, after asking the question:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set /p test=Tell me something?&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I don’t often use this, as it somewhat defeats the purpose of automation – I prefer to have all the required input in a control file, which separates the intended action from the actual operator.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Set with Delayed expansion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Delayed environment variable expansion provides a method of executing commands and storing the output for use by other commands within a loop – either in different iterations or nested commands. This is required when looping through ‘for’ commands or nesting commands, otherwise state between each command is not maintained.&lt;br /&gt;&lt;br /&gt;For example, without delayed expansion, the following would not work:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set test=test variable &amp;amp; echo %test%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;However, using delayed environment variable expansion, this problem can be easily overcome, using the !variable! syntax, instead of the normal %variable%. Note that you may need to enable delayed environment variable expansion, which can be done using ‘cmd /v:on’ when starting the command prompt, or running ‘setlocal ENABLEDELAYEDEXPANSION’ within an existing shell.&lt;br /&gt;&lt;br /&gt;With delayed expansion, the first command would set the variable and the second echo the newly set variable:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set test=test variable &amp;amp; echo !test!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or to re-use an example above, calculate next year and then do something with that information (echo in this case):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3 delims=/" %i in ('echo %date%') do set /a NextYear=%i+1 1&gt;nul &amp;amp; echo Next year is !NextYear!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Unless there is already a variable of the same name, running the commands above using the percent signed variables will result in the variable name being printed, as the environment hasn’t yet been changed by the first command.&lt;br /&gt;&lt;br /&gt;Note that while testing, it seems the Vista command shell has been updated and as long as delayed expansion is enabled, this command would work:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set test=test variable &amp;amp; echo %test%&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following command is a one-line version of the batch above, using delayed variable expansion to calculate the variables as each command is executed:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=1-8 delims=.- " %i in ('echo 192.168.11.40 255.255.254.0') do set /a Octet1="%i &amp;amp; %m" &gt;nul &amp;amp; set /a Octet2="%j &amp;amp; %n" &gt;nul &amp;amp; set /a Octet3="%k &amp;amp; %o" &gt;nul &amp;amp; set /a Octet4="%l &amp;amp; %p" &gt;nul &amp;amp; Echo %i.%j.%k.%l,!Octet1!.!Octet2!.!Octet3!.!Octet4!,%m.%n.%o.%p&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An easier example to follow, set the environment variable called ‘number’ to a random number (using %random% - very useful), echo the newly set variable, and then use ‘set /a’ to increment the number by one:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;set number=%random% &amp;amp; echo !number! &amp;amp; set /a number=!number!+1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you are using nested ‘for’ commands, you can just reference variables from an earlier command, but in some circumstances delayed expansion is the only possibility. I have had to use this syntax when using ‘set /a’ and using the replace/substring functionality, as this requires a full variable (eg. %path%, not a temporary %i type variable.&lt;br /&gt;&lt;br /&gt;This was a basic overview of ‘set’ and some of the ways in which I use this command when automating tasks at the command-line.&lt;br /&gt;&lt;br /&gt;For more real-world examples of how I use ‘set’, see my command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7407876905744133091?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7407876905744133091' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7407876905744133091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7407876905744133091'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/command-line-automation-set.html' title='Command-line automation – set'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-458249775341935659</id><published>2008-12-18T15:23:00.004+10:00</published><updated>2008-12-27T22:48:48.524+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Command-line automation – errorlevels and if</title><content type='html'>This is the third in a series of posts containing information on what I consider the building blocks to automate repetitive tasks at the Windows command-line.  These components are the for, find, findstr, set, if and echo commands, control files used to control data input, combined with errorlevels, command concatenation, nested loops and if/then/else constructs.&lt;br /&gt;&lt;br /&gt;Described in this post are errorlevels, and if/then/else statements, useful for branching in a single command-line to execute based on the error level set or some other condition.&lt;br /&gt;&lt;br /&gt;Using errorlevels, concatenated commands and if/then/else statements provides enhanced functionality, and most complex operations would not be possible on a single command-line without these features.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;errorlevels&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In the context of command-line automation, I find error levels most useful when trying to cater for both sets of outcomes when executing a command – either what you wanted happened, or it didn’t.&lt;br /&gt;&lt;br /&gt;In the previous examples, I’ve used a control file to ping one or more machines and then echoed the IP address of those that were contactable.  This is only part of the picture – what about those machines in the list that didn’t respond to a ping?  They are simply dropped from the output.  This may be what you are after, but normally I would prefer to know the positive and the negative.&lt;br /&gt;&lt;br /&gt;To work around this problem, the following command could be used:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3 delims=: " %i in ('"ping -n 1 computer &amp;#124; find /i "reply" &amp;amp; if errorlevel 1 echo 0:1:Not-Found"') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This will ping ‘computer’, echo the IP Address if found, otherwise echo NotFound.  This occurs because the find command sets the errorlevel according to whether the string was found, and then we are concatenating the command with another to check if an errorlevel occurred indicating the string was not found, and echoing an alternate output to be picked up by the body of the for loop.&lt;br /&gt;&lt;br /&gt;A simpler way of looking at this may be without the ‘for’ loop:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ping -n 1 computer &amp;#124; find /i "reply" &gt;nul &amp;amp; if errorlevel 1 (echo No Reply) else (echo Replied)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The command is similar to the example above, it will ping ‘computer’, and if the word reply was found in the output, it will print ‘replied’, otherwise it will print ‘no reply’.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Command concatenation and if/then/else&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Commands can be concatenated – when running natively or inside a ‘for’ loop – providing a simple method to group commands.  For example, looping through a control file, you might want to nslookup and then ping each device:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (c:\temp\control.txt) do nslookup %i &amp;amp; ping %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This is a simple chain of commands, execute one and then the other.  However, provided each command returns a relevant errorlevel, the if/then/else syntax can also be used to execute the second only if the first succeeded.&lt;br /&gt;&lt;br /&gt;Unfortunately nslookup does not provide an errorlevel, but the find command does:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ping -n 1 computer &amp;#124; find /i "reply" &gt;nul &amp;amp; if errorlevel 1 (echo No Reply) else (echo Replied)&lt;br /&gt;ping -n 1 computer &amp;#124; find /i "reply" &gt;nul &amp;amp;&amp;amp; echo Replied &amp;#124;&amp;#124; echo No Reply&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The above commands return the same result – they each print a statement depending on whether ‘reply’ was found in the ping output, the second using the shorthand ‘if’ (&amp;amp;&amp;amp;) and ‘else’ (&amp;#124;&amp;#124;) syntax.&lt;br /&gt;&lt;br /&gt;‘If’ can be used to check the errorlevel (as in the above example), check whether one string equals another, and check whether a file/directory exists.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;If ErrorLevel checking&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;The following examples send an invalid service a stop control, and perform various checks on the errorlevel returned. Note that sc.exe on XP does not return error codes, this was Vista which does at least return 1060 when the specified service does not exist.&lt;br /&gt;&lt;br /&gt;Check whether errorlevel (a special variable that can either be enclosed in % or not) was exactly 1060:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sc stop invalidservice &gt;nul &amp;amp; if errorlevel==1060 echo Service not found&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Check whether errorlevel was exactly 1060, if so echo ‘service not found’, otherwise echo the errorlevel returned:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sc stop invalidservice &gt;nul &amp;amp; if errorlevel==1060 (echo Service not found) else (echo Error code %errorlevel% returned)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Check whether the errorlevel was 1060 or greater, and not 1061 (therefore only 1060). &lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sc stop invalidservice &gt;nul &amp;amp; if errorlevel 1060 if not errorlevel 1061 echo Service not found&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Check if anything above errorsuccess (0) was returned, echoes an error occurred and then uses ‘net helpmsg’ to return the error description for the specified error code:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sc stop invalidservice &gt;nul &amp;amp; if errorlevel 1 echo An error occurred: %errorlevel% &amp;amp; net helpmsg %errorlevel%&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;If string checking&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;If can be used to conditionally check two strings to determine the action taken.  Note that if the string could be blank, you’ll need to either append/prepend another character or enclose the string in quotes.&lt;br /&gt;&lt;br /&gt;Using the above example of pinging a computer, check the response and branch accordingly (different echoes in this case):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3 delims=: " %i in ('"ping -n 1 computer &amp;#124; find /i "reply" &amp;amp; if errorlevel 1 echo 0:1:Not-Found"') do if "%i"=="reply" (echo Ping success) else (echo Ping failed)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Note that ‘if /i’ can be used for a case insensitive comparison.&lt;br /&gt;&lt;br /&gt;Additionally, if command extensions are enabled, and the strings in comparison are numeric, both are converted to numbers and additional operators are available for the comparison, for example:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;If 9 equ 9 echo Equals&lt;br /&gt;If 5 lss 14 echo Less than&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;If exist&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;To determine whether a file or directory exists, the ‘if exist’ syntax can be used.  This can be useful when checking flag files or control files exist to avoid encountering unexpected errors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;If exist %windir% echo %windir% exists&lt;br /&gt;If not exist c:\temp\control1.txt (echo Control File does not exist, terminating &amp;amp; break) else (echo continuing)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Some other examples of concatenating commands which help to demonstrate the concepts:&lt;br /&gt;&lt;br /&gt;Use ‘sc.exe’ to send a service a stop control, if the service was running (exists, security allows etc) and was sent a stop, sc will return errorsuccess (0), pause for 5 seconds and then restart the service, otherwise echo that the service was not running in the first place:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;sc stop "service" &amp;amp;&amp;amp; (echo error %errorlevel% &amp;amp; sleep 5 &amp;amp; sc start "service") &amp;#124;&amp;#124; echo Service was not running, error %errorlevel%&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;nslookup www.microsoft.com, find the second address (the first in nslookup is the DNS server address, and echo that address:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1 tokens=2" %i in ('"nslookup www.microsoft.com 2&gt;nul &amp;#124; find /i "address""') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;nslookup www.microsoft.com, skip the first DNS server address (the second line of the nslookup output – find /n), return the other address if found, otherwise return ‘Not-Found’ in the %i variable – the second token of the string:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=2" %i in ('"nslookup www.microsoft.com 2&gt;nul &amp;#124; find /i /n "address" &amp;#124; find /i /v "[2]" &amp;amp; if errorlevel 1 echo Address Not-Found"') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Create a file, if the file is found type the contents, and then delete the file if the type succeeded, otherwise report that the ‘type’ command failed:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;echo test &gt; %temp%\test.txt &amp;amp; if exist %temp%\test.txt type %temp%\test.txt &amp;amp;&amp;amp; del %temp%\test.txt &amp;#124;&amp;#124; Echo could not type %temp%\test.txt&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This was a basic overview of the errorlevels and if/then/else branching, future posts will build on this with other useful commands and nested ‘for’ loops.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For more real-world examples of how I use errorlevels and if/then/else, see my command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-458249775341935659?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=458249775341935659' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/458249775341935659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/458249775341935659'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/command-line-automation-errorlevels-and.html' title='Command-line automation – errorlevels and if'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8315872520483122238</id><published>2008-12-17T12:46:00.004+10:00</published><updated>2008-12-27T22:48:05.996+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Command-line automation – find and findstr</title><content type='html'>This is the second in a series of posts containing information on what I consider the building blocks to automate repetitive tasks at the Windows command-line. These components are the for, find, findstr, set, if and echo commands, control files used to control data input, combined with errorlevels, command concatenation, nested loops and if/then/else constructs.&lt;br /&gt;&lt;br /&gt;Described in this post are the ‘find’ and ‘findstr’ commands - unless you want to spend all your time manually creating or filtering control files you will often use these commands when constructing repeatable command-lines.&lt;br /&gt;&lt;br /&gt;These two commands are crucial in efficient ‘for’ loop processing, invaluable when filtering a control file or the results of an in-line command. Help on each is available from the command prompt with the ‘/?’ argument.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Find&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;I usually use find because more often than not I want to filter a string literal – a specific word or combination of characters – from an input string. As often as not, I also use ‘find /v’, returning the lines that don’t match the specified string.&lt;br /&gt;&lt;br /&gt;For example, if you have a control file listing servers in several geographic locations, but you are only interested in processing servers in ‘bne’ (case insensitive with ‘/i’), you could run:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;find /i "bne" c:\temp\control.txt&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Combined with a ‘for’ command, this could be:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=2" %i in ('find /i "bne" c:\temp\control.txt') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Note that this line uses the following syntax explained in the previous post on ‘for’:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;‘Skip=2’ tells the loop to skip the first two lines – the result header of the ‘find’ command&lt;/li&gt;&lt;li&gt;Inside the brackets I’ve specified to run a command and parse the results, wrapping the command in single-quotes. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The results are that for each server containing the word ‘bne’, the body of the ‘for’ statement will be executed – in this case simply to echo the first token.&lt;br /&gt;&lt;br /&gt;You might also want to run the commands against all servers except those in bne, which is the above command repeated with the addition of the ‘/v’ switch to tell ‘find’ to return those lines not containing a match:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1" %i in ('find /i /v "bne" c:\temp\control.txt') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;em&gt;Filtering in-line output with find&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Filtering output of a command executed within a ‘for’ loop is syntactically a little more complicated, but makes sense once you get the hang of it. For example, suppose you want to filter the output of a ping command, returning the IP address of those hosts that replied to a ping, you could run:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3" %i in ('"ping -n 1 computer  find /i "reply""') do @echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This will:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Execute the ping command, pinging the host named computer, filtering the output to find the word ‘reply’ (indicating a successful reply). Note that to use the pipe inside the brackets, the whole string needs to be enclosed in double-quotes – inside the single-quotes.&lt;/li&gt;&lt;li&gt;Using spaces/tabs, choose the third token to return in the first variable - %i. This will be the IP address in the standard ping output returned by XP and Vista. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Unfortunately the third token of the ping output includes a irrelevant colon, so to strip that, we could specify colons and spaces as delimiters in the for loop:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "tokens=3 delims=: " %i in ('"ping -n 1 computer  find /i "reply""') do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This will be better explained in a future post, but you can also nest two ‘for’ commands and for each host in the control file (in bne in this example), ping and return the IP address if there is a reply:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=2" %i in ('find /i "bne" c:\temp\control.txt') do @for /f "tokens=3 delims=: " %m in ('"ping -n 1 %i  find /i "reply""') do @echo %i,%m&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The output would give you a comma-separated list of server names and IP address of those from the original control file that currently respond to a ping. Theoretically not all that useful with servers, as they’d usually be known IPs and always on, but if you’re wanting to check something on hundreds or thousands of workstations this would give you a point-in-time control file of online machines (assuming name resolution is accurate).&lt;br /&gt;&lt;br /&gt;It’s also worth noting that ‘find’ commands can be cascaded – piping the output of one find command to another if you need to further refine the output. For example to find servers in ‘bne’ and then servers in ‘bne’ that also contain ‘vm’:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;find /i /c "bne" c:\temp\control.txt  find /i "vm"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The possibilities are nearly endless, I use ‘find’ to:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Filter in and out items that I want, ‘find /i’ and ‘find /i /v’ from generic control files that I use for multiple operations, either in-line in a for command, or to create a stand-alone filtered control file&lt;/li&gt;&lt;li&gt;Run commands and then filter out useless or useful information, often headers/footers or other extraneous detail, making it possible to list data, filter that data and run a command against each filtered item in a single command.&lt;/li&gt;&lt;li&gt;Use errorlevels to determine whether the find command was successful or not (explained in a future post). Often the only way of knowing whether a command returned what you were after is the presence or absence of a string – and ‘find’ will tell you this based on the errorlevel (an advantage over findstr which in XP at least does not set the errorlevel).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Note that find also has several other features that are useful in some scenarios:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;By default, offline files will be skipped – if you use a file archiving product that sets the offline (‘O’) attribute, these files will not be searched unless you specify the /offline parameter&lt;/li&gt;&lt;li&gt;The ‘find /n’ option will return the line number the match was found, occasionally useful when parsing large or sequenced control files and you want to know where in a file the string was found.&lt;/li&gt;&lt;li&gt;The ‘find /c’ option will return a count of the matches found, instead of the actual matching lines. This can often be useful when determining how many records would be processed. For example, in the example above you could first run the following command to determine how many records would be processed with the for loop:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;find /i /c "bne" c:\temp\control.txt&lt;/span&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Findstr&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;These same principles can be used with findstr to filter output – findstr provides advanced searching, with the following benefits in my use of the commands, you can:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Search for more than one string in a single command. This simplifies searches, in the example above, you could search for ‘bne’ and ‘syd’ in a single findstr command.&lt;/li&gt;&lt;li&gt;Use basic regular expressions and/or string literals&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In the example above with a control file containing a list of servers with geographic names (or descriptions somewhere on the line), you could run the following command to return servers in both syd and bne and then run the subsequent command against each server:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in ('findstr /i /c:bne /c:syd c:\temp\control.txt') do echo %i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Regular expressions are used to group similar items, without expressly providing each possible combination. For example, parsing robocopy log output, to search for new directories that have been created with a regular expression, you could run:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;findstr /i /n "^.*New.Dir" Robocopy.log"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;You could just use ‘find’ and search for the string ‘new dir’, but this could easily return false positives if a file or directory has the string ‘new dir’ in it. Using the regular expression looking for the start of the line followed by whitespace followed by the ‘New Dir’ is much more precise.&lt;br /&gt;&lt;br /&gt;This was a basic overview of the ‘find’ and ‘findstr’ commands, future posts will build on this foundation with other useful commands, error levels, if/then/else statements and nested ‘for’ loops.&lt;br /&gt;&lt;br /&gt;For more real-world examples of how I use the ‘find’ and ‘findstr’ commands, see my command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8315872520483122238?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8315872520483122238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8315872520483122238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8315872520483122238'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/command-line-automation-find-and.html' title='Command-line automation – find and findstr'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-597128891255443595</id><published>2008-12-16T15:10:00.004+10:00</published><updated>2008-12-27T22:47:32.474+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>Building blocks of command-line automation – FOR</title><content type='html'>&lt;p&gt;This is the first in a series of posts containing information on what I consider the building blocks to automate repetitive tasks at the Windows command-line. These components are the for, find, findstr, set, if and echo commands, control files used for data input, combined with errorlevels, command concatenation, nested loops and if/then/else constructs.&lt;br /&gt;&lt;br /&gt;Described in this post is the ‘for’ command, the most important component in command-line automation. This command provides several methods of looping through a list, and running a command against each element in that list. Use the ‘for /?’ to get Microsoft help on this command.&lt;br /&gt;&lt;br /&gt;Using the ‘for’ command with one of the syntaxes below provides many benefits, including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Repeatability – If you save the command you run, it can be re-run several or hundreds of times&lt;/li&gt;&lt;li&gt;Change control and testing – It’s easy to record what you are planning and simple to run the same commands in a test-lab environment. The output of commands can also be redirected to file, making accountability much easier. Using control files also provides a straightforward method of recording the targets of various actions, knowing that you have one master list, and do not risk accidentally missing an entry.&lt;/li&gt;&lt;li&gt;Documentation – Implementation using a series of commands very easily translates to an as-built document – with the added benefit of providing a quicker DR process.&lt;/li&gt;&lt;li&gt;Efficiency – Even though designing the command for the first run may not be as quick as using the GUI, every time after that will usually be much quicker, and previous commands can often be quickly adapted to new tasks. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can use the ‘for’ command to:&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Process a set of filenames or string literals&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The filenames or literals can either be directly named in a space-separated set, or you can use wildcards to process more than one file. For example:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (*.txt) do echo %i&lt;br /&gt;for %i in (test1.txt test2.txt) do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;For example, I would use this syntax if I’m trying to:&lt;br /&gt;&lt;br /&gt;Quickly execute something against a group of machines, eg ping each machine:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (server1 server2 server3 server4) do ping -n 1 %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Process a series of data files that I have created from another process, eg this uses the regview utility to export the registry entries modified by *.pol files into *.txt:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (*.pol) do regview %i &gt; %i.txt&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Quickly execute the same command with a different variable, eg use the setprinter utility to view all levels of configuration for the specified printer (you could also use for /l in this example):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (0 1 2 3 4 5 6 7 8 9) do setprinter -show \\server\printer %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Process a set of directories&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The directory names can either be directly named in a space-separated set, or you can use wildcards to process more than one directory. For example:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /d %i in (%windir%\*) do echo %i&lt;br /&gt;for /d %i in (c:\temp c:\windows) do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I would use this syntax if I’m trying to do something with each top-level directory, for example:&lt;br /&gt;&lt;br /&gt;Report or set ACLs:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /d %i in (%rootDir%\*) do icacls %i /save %~ni.txt&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Rename all the top-level directories to start with a new prefix:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /d %i in (%rootDir%\*) do ren %i New-%~ni&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Process the contents of a text file, line by line&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The contents of a file – which I usually refer to as a control file – can be read line-by-line and your command would be run once for each line, substituting tokens from the control file. This provides unlimited capability – construct a control file through any means available and you can then process the entries one-by-one and run a command against that entry.&lt;br /&gt;&lt;br /&gt;Note that in Vista at least, just a LF is enough to separate the lines, rather than the Windows standard CR+LF.&lt;br /&gt;&lt;br /&gt;For example, assuming you have a control file with a list of servers or workstations, you could:&lt;br /&gt;&lt;br /&gt;Lookup the IP address of each machine:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (test.txt) do nslookup %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Ping each machine:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (test.txt) do ping %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Remote dir of each machine:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (test.txt) do dir \\%i\c$&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I use this constantly to run a command against multiple AD objects, machines, printers, or other network devices, whether the command queries or checks something, or makes a change to each device.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Process the results of a command, line by line&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The results of almost any command can be used as the looping mechanism for a ‘for /f’ command, providing an in-memory control file. For example, you could:&lt;br /&gt;&lt;br /&gt;Find the local hostname and then nslookup the computer (you could also use %computername% for this):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in ('hostname') do nslookup %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Query the local Active Directory for a list of DCs (server records) and lookup the IP of each DC:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in ('dsquery server -o rdn') do nslookup %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Recursively enumerate a path&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;It’s possible to recursively enumerate files or directories from a specified starting location, passing each to the body of the for loop. This provides a rudimentary search and response facility, allowing you to traverse a tree looking for objects of a particular type – and then execute something for each found.&lt;br /&gt;&lt;br /&gt;For example, you could search from the root of C: for *.txt files, and then report the filename and size (you would just use dir /s if all you wanted to do was echo)&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /r c:\ %i in (*.txt) do echo %i %~zi&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Step through a sequence of numbers and execute for each&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The ‘for /l’ option allows stepping through a sequence of numbers, passing the number as a parameter to the body of the ‘for’ loop. &lt;/p&gt;&lt;p&gt;I don’t use this method very often, but it would be another method to the setprinter command above:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /l %i in (1,1,9) do setprinter -show \\server\printer %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Variable Expansion&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;When using ‘for’, ‘for /f’ and ‘for /d’ variable references can also be modified to return substrings or additional information. Note that when using ‘for /f’, most of these only make sense if you are processing lists of files or directories, but if you did have a control file with files/paths variable expansion does work as expected.&lt;br /&gt;&lt;br /&gt;This substitution can be very useful, particularly when constructing parameters to pass to the command in the body of the ‘for’ loop. For Example:&lt;br /&gt;&lt;br /&gt;If you had a number of control files that you wanted to process, outputting the results to a same-named log file:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (c:\temp\*.txt) do echo Do something with %i &gt; %~ni.log&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;If the output of a previous command wrapped the results in quotes, but you need to append/prepend something else you can easily remove surrounding quotes:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in ('echo "c:\windows"') do echo %~i\temp&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Given a list of files, echo those that are zero bytes in size:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (c:\temp\*.txt) do @if %~zi == 0 @echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Given a full path, split into drive, path and filename:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for %i in (c:\windows\temp\test.txt) do echo %~di %~pi %~nxi&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Tokens, delimiters and skipping lines&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;The simple functionality of the ‘for /f’ command can be extended very easily with three options:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Tokens – By default only the first token is returned in the variable specified. You can change this behaviour to return one or more tokens, eg tokens=2,3,5 or tokens=1-3 would populate %i, %j and %k with the respective tokens&lt;/li&gt;&lt;li&gt;Delimiters – Instead of the normal space and tab delimiters, one or more alternate characters can be specified. For example, you can specify a comma as a delimiter to process as CSV file&lt;/li&gt;&lt;li&gt;Skipping lines – the skip command can be used to skip one or more lines from the start of a control file, useful when trying to skip a header line, or bypass logo information in a command result. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;These options can be used individually or as a combination, for example:&lt;br /&gt;&lt;br /&gt;Skip the first line of the control file:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1" %i in (test.txt) do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Skip the first line, and use comma’s as the delimiter:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=1 delims=," %i in (test.txt) do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Skip the first two lines, use the second token, separated by comma and space:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f "skip=2 tokens=2 delims=, " %i in (test.txt) do echo %i&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;This was a basic overview of the ‘for’ command, future posts will build on this foundation with multiple commands, error levels, if/then/else statements and nested ‘for’ loops.&lt;br /&gt;&lt;br /&gt;For more real-world examples of how I use the ‘for’ command, see my command-line operations:&lt;br /&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-general-command-line-operations.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-dns-dhcp-and-wins-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:78%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html"&gt;&lt;span style="font-size:78%;"&gt;http://waynes-world-it.blogspot.com/2008/09/useful-active-directory-command-line.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-597128891255443595?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=597128891255443595' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/597128891255443595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/597128891255443595'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/building-blocks-of-command-line.html' title='Building blocks of command-line automation – FOR'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4074673528194553999</id><published>2008-12-11T22:40:00.002+10:00</published><updated>2009-01-09T00:25:20.203+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Useful PowerShell command-line operations</title><content type='html'>The commands below are a small but growing list of powershell one-liners I've used (and when I remember to take note).  Note that this may not be the best and almost certainly isn't the only way in most cases.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at a PowerShell command prompt, or you can use the commands as part of a PS1 script file if you prefer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Show help on commands such as 'if', regular expressions etc&lt;/u&gt;&lt;br /&gt;help about*&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show help about about_Automatic_variables such as $_ $DebugPreference $OFS&lt;/u&gt;&lt;br /&gt;help about_Automatic_variables &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run a command and pipe the results to a variable&lt;/u&gt;&lt;br /&gt;cscript.exe //nologo script.wsf &amp;#124; Set-Variable -name scriptResults&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run a command and set a variable with the output&lt;/u&gt;&lt;br /&gt;$scriptResults = cscript.exe //nologo script.wsf&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run a command and set a variable with the output using the call operator&lt;/u&gt;&lt;br /&gt;$scriptResults = &amp; cscript.exe //nologo script.wsf&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Filter an object based on an array of strings&lt;/u&gt;&lt;br /&gt;$array = "a", "b"; write-output a b c d &amp;#124; select-string -pattern $array -simpleMatch&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reformat today's date to YYYYMMDD&lt;/u&gt;&lt;br /&gt;$today = [DateTime]::Now.ToString("yyyyMMdd") &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find local disks except C: using powershell and output to CSV&lt;/u&gt;&lt;br /&gt;Get-WmiObject -Namespace root\cimv2 -ComputerName %server% -Query "SELECT * from Win32_LogicalDisk WHERE FileSystem='NTFS' AND Description = 'Local Fixed Disk' AND Name != 'C:'" &amp;#124; export-csv c:\disk.csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use the VI Toolkit Powershell snap-in to query for snapshots&lt;/u&gt;&lt;br /&gt;Get-VM &amp;#124; Get-Snapshot &amp;#124; export-csv -path c:\temp\VMsnapshots.csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use the VI Toolkit Powershell snap-in to query for snapshot information&lt;/u&gt;&lt;br /&gt;Get-VM &amp;#124; Get-Snapshot &amp;#124; foreach-object {$out=  $_.VM.Name + "," + $_.Name + "," + $_.Description + "," + $_.PowerState; $out}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Start a remote process using Powershell/WMI&lt;/u&gt;&lt;br /&gt;$computer = "."; ([WMICLASS]"\\$computer\root\CIMv2:win32_process").Create("notepad.exe")&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote processes and the command-line parameters with PowerShell&lt;/u&gt;&lt;br /&gt;Get-WmiObject win32_process &amp;#124; Format-Table ExecutablePath,Caption,CommandLine,CreationDate,WorkingSetSize,ProcessId&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Generate a password 10 characters in length, at least 5 punctuation marks&lt;/u&gt;&lt;br /&gt;[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Web") ; [System.Web.Security.Membership]::GeneratePassword(10,5)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Format a date to XML XSD:dateTime&lt;/u&gt;&lt;br /&gt;$Now = [DateTime]::Now.ToString("yyyy-MM-ddTHH:mm:ss")&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check if the given variable is an object&lt;/u&gt;&lt;br /&gt;if ($variable -is [object]) {}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check which network connections (drive mappings) a 2003 computer has&lt;/u&gt;&lt;br /&gt;get-WMIObject -computerName "$env:computername" -class win32_logicaldisk -property ProviderName, DeviceID -filter "DriveType=4" &amp;#124; Format-List -property ProviderName, DeviceID&lt;br /&gt;&lt;br /&gt;&lt;u&gt;See whether an IP can be resolved to a host name&lt;/u&gt;&lt;br /&gt;[System.net.Dns]::GetHostEntry($IP)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;See whether a host name can be resolve to an IP&lt;/u&gt;&lt;br /&gt;$ip = &amp; { trap {continue}; [System.net.Dns]::GetHostAddresses($computer) }&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View the datastore information for the available storage&lt;/u&gt;&lt;br /&gt;get-vc -server $server ; Get-Datastore&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check if a file or path exists or not&lt;/u&gt;&lt;br /&gt;test-path -path $path  ; if (!(test-path -path $path)) {write-output "$path does not exist"}&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use psexec to run a powershell command remotely and report to stdout (eg query 'remote' event logs in this example)&lt;/u&gt;&lt;br /&gt;psexec \\machine /s cmd /c "echo. &amp;#124; powershell . get-eventlog -newest 5 -logname application &amp;#124; select message"&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4074673528194553999?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4074673528194553999' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4074673528194553999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4074673528194553999'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/useful-powershell-command-line.html' title='Useful PowerShell command-line operations'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3481543522727934544</id><published>2008-12-11T22:07:00.004+10:00</published><updated>2008-12-11T22:15:07.579+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Cluster'/><title type='text'>MSCS 2003 Cluster Virtual Server Components</title><content type='html'>This post provides my interpretation of a simple MSCS 2003 virtual server with a file share, including how the cluster interacts with the OS and network services to provide access to the share. This follows on from the last post on low-level detail of file access in an attempt to provide a clearer picture of these often taken-for-granted components.&lt;br /&gt;&lt;br /&gt;Note that this is only my opinion, based on less-than complete knowledge and more than likely contains semantic errors if nothing else.&lt;br /&gt;&lt;br /&gt;File &amp;amp; Print Cluster Native x64 (EM64T/AMD64)&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Cluster Service. Includes Checkpoint Manager, Database Manager, Event Log Replication Manager, Failover Manager, Global Update Manager, Log Manager, Membership Manager, Node Manager. &lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;Operating System Interaction with the LanManServer Service which advertised shares.&lt;/li&gt;&lt;li&gt;NetBIOS registration of the virtual server name through existing network services&lt;/li&gt;&lt;li&gt;DNS registration of the virtual server name through existing network services&lt;/li&gt;&lt;li&gt;Kerberos SPNs registered against an AD computer account through Active Directory&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Resource Monitor. Spawned child process of the cluster service, separate resource monitors can exist for resource DLLs&lt;/li&gt;&lt;li&gt;ClusRes.dll Physical Disk &lt;-&gt; IsAlive/LooksAlive SCSI reservation and directory access. LooksAlive issues a SCSI reservation every 3 seconds through ClusDisk.sys against all managed disks. IsAlive performs a ‘dir’ equivalent&lt;/li&gt;&lt;li&gt;ClusRes.dll Network Name &lt;-&gt; IsAlive/LooksAlive check on NetBT/DNS registration. LooksAlive relies on MSCS NIC failure detection. IsAlive queries local TCP/IP stack for virtual IP and the NetBT driver if NetBIOS is enabled&lt;/li&gt;&lt;li&gt;ClusRes.dll IP Address &lt;-&gt; IsAlive/LooksAlive check on cluster NIC. LooksAlive queries NetBT driver and every 24 hours issues a dynamic DNS host record registration. If ‘DNS is required’ resource will fail if DNS registration fails. Same test for IsAlive&lt;/li&gt;&lt;li&gt;ClusRes.dll Resource DLL File Shares &lt;-&gt; IsAlive/LooksAlive check on file share visibility. LooksAlive queries lanmanserver service for the share name. IsAlive does the same, and if unlimited users, the first file on the share is copied&lt;/li&gt;&lt;li&gt;32-bit Resource Monitor WOW64, Eg. Enterprise Vault Cluster application. Third-party cluster resources, eg Enterprise Vault, which in this case notifies the local FSA placeholder service on each physical node of virtual server changes&lt;/li&gt;&lt;li&gt;ABE enabled by generic cluster resource. Access based enumeration with a generic cluster application running abecmd.exe during virtual server/share creation. Uses 32-bit cluster resource monitor with WOW64, setting SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM (0x0800) flag set on the otherwise standard share.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;Pretty picture view:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_ErSjACRvSfI/SUEDWigDRII/AAAAAAAAEOw/o9aNkMu2Y5M/s1600-h/Blog100_ClusterVirtualServer.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5278503924008174722" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 331px; CURSOR: hand; HEIGHT: 400px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_ErSjACRvSfI/SUEDWigDRII/AAAAAAAAEOw/o9aNkMu2Y5M/s400/Blog100_ClusterVirtualServer.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;strong&gt;References&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Server side processes for simple file access&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/11/server-side-process-for-simple-file.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/11/server-side-process-for-simple-file.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Access Based Enumeration&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet.microsoft.com/en-us/library/cc784710.aspx"&gt;&lt;span style="font-size:85%;"&gt;http://technet.microsoft.com/en-us/library/cc784710.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;SHARE_INFO_1005 Structure&lt;br /&gt;&lt;/span&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb525404.aspx"&gt;&lt;span style="font-size:85%;"&gt;http://msdn.microsoft.com/en-us/library/bb525404.aspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3481543522727934544?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3481543522727934544' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3481543522727934544'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3481543522727934544'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/12/mscs-2003-cluster-virtual-server.html' title='MSCS 2003 Cluster Virtual Server Components'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_ErSjACRvSfI/SUEDWigDRII/AAAAAAAAEOw/o9aNkMu2Y5M/s72-c/Blog100_ClusterVirtualServer.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-9058348783511195239</id><published>2008-11-07T17:06:00.005+10:00</published><updated>2008-11-07T17:18:43.431+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='x64'/><category scheme='http://www.blogger.com/atom/ns#' term='Cluster'/><title type='text'>Server-side process for simple file access</title><content type='html'>This post provides my interpretation of what happens at a low level when a user on a workstation tries to access a file on a server - in this case a Windows server 2003 x64 MSCS cluster. I was trying to demonstrate the complexity of what seems like such a simple action, and in particular trying to incorporate the cluster network/disk elements and highlighting the WOW64 side of things when you are running x64 with x86 third-party software (such as archiving, quotas etc).&lt;br /&gt;&lt;br /&gt;Note that I'm reasonably confident this isn't correct because my understanding if lacking, combined with lack of time/information, but even if it were accurate in content, the step-by-step / flowchart views aren't the best way to represent these multi-layered processes. But anyway, somebody else might also think it interesting (nerds!)&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Workstation redirector file access to a virtual node in the cluster. Includes DNS/NetBIOS calls to determine the cluster virtual server IP address &lt;/li&gt;&lt;li&gt;LanManServer service. User-mode LAN Manager 2.x server service, providing file and print sharing, and with 2003 SP1, Access Based Enumeration &lt;/li&gt;&lt;li&gt;NDIS layer. Network Driver Interface Specification, Hardware interrupts passing frames to the NIC driver, then passed to the bound transport driver. send and receive raw packets, includes LLC &lt;/li&gt;&lt;li&gt;TDI Layer. Single interface for upper-level clients to access transport providers, such as TCP/IP &lt;/li&gt;&lt;li&gt;ClusNet.sys Driver. Cluster specific driver interpreting and routing intracluster traffic and determining communication failure &lt;/li&gt;&lt;li&gt;Srv.sys Server Service. SMB file server driver, kernel-mode companion to the LanManServer service &lt;/li&gt;&lt;li&gt;I/O Manager. I/O support routines, I/O Request Packets (IRPs) and Fast I/O interfaces &lt;/li&gt;&lt;li&gt;FSD Manager. File System Driver Manager, loads FSDs and legacy file system filters, interacts with the file system cache manager. &lt;/li&gt;&lt;li&gt;Filter Manager. A file system filter that provides a standard interface for minifilters, managing altitudes and connectivity to the file system stack. Interacts with the file system cache manager, and in the case of x86 filters, an instance of WOW64 controls the runspace for the filters (on an x64 platform) &lt;/li&gt;&lt;li&gt;File System Cache Manager. A file system filter, working with kernel memory-mapped and paging routines to provide file level caching &lt;/li&gt;&lt;li&gt;ntfs.sys File System FSD. Windows NT File System driver, creates a Control Device Object (CDO) and Volume Device Object (VDO) &lt;/li&gt;&lt;li&gt;ClusDisk.sys upper-level storage filter driver. Cluster specific storage filter driver maintaining exclusive access to cluster disks using SCSI reserve commands &lt;/li&gt;&lt;li&gt;Volume Snapshot Volsnap.sys. Manages software snapshots through a standard storage filter &lt;/li&gt;&lt;li&gt;Volume Manager ftDisk.sys. Presents volumes and manages I/O for basic and dynamic disk configurations &lt;/li&gt;&lt;li&gt;Partition Manager Partmgr.sys. Filter driver that sits on top of the disk driver, creates partition devices, notifies volume manager and exposes IOCTLs &lt;/li&gt;&lt;li&gt;Class Driver disk.sys. Presents a standard disk interface to the storage stack, creating a Function Device Object (FDO) &lt;/li&gt;&lt;li&gt;Storage Port Driver - Storport. Assists with PnP and power functionality, providing a Physical Device Object (PDO) for the device-&gt;bus connection &lt;/li&gt;&lt;li&gt;Miniport Driver. Interface to the storage adapter’s hardware, combining with the storport driver to create the storage stack &lt;/li&gt;&lt;li&gt;SMB response to the client. SMB response to the redirector on the workstation requesting the file&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Pretty picture view:&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_ErSjACRvSfI/SRPq7mm3XZI/AAAAAAAAEMA/IFWXsz-2v7k/s1600-h/Blog99_AccessingFilesThroughCluster.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5265810699022982546" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 198px; CURSOR: hand; HEIGHT: 400px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_ErSjACRvSfI/SRPq7mm3XZI/AAAAAAAAEMA/IFWXsz-2v7k/s400/Blog99_AccessingFilesThroughCluster.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-9058348783511195239?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=9058348783511195239' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/9058348783511195239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/9058348783511195239'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/11/server-side-process-for-simple-file.html' title='Server-side process for simple file access'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_ErSjACRvSfI/SRPq7mm3XZI/AAAAAAAAEMA/IFWXsz-2v7k/s72-c/Blog99_AccessingFilesThroughCluster.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8243600655559478734</id><published>2008-11-02T17:04:00.006+10:00</published><updated>2008-12-23T11:59:20.328+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Operations Manager 2007'/><category scheme='http://www.blogger.com/atom/ns#' term='Scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>OpsMgr 2007 performance script - VMware datastores</title><content type='html'>This post provides a method of collecting VirtualCenter datastore information for ESX hosts in one or more clusters as performance data in Operations Manager 2007. You can then trend datastore usage for longer term analysis, and alert on the data for proactive problem management. This is my first attempt at using script to gather performance data in OpsMgr 2007, and my lack of OpsMgr knowledge combined with the limited documentation/examples made this difficult and possibly harder than it needs to be.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Background&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In OpsMgr 2007, I thought it would be useful to report on LUN disk space on the ESX side of things in a similar fashion to agent-based Windows disk performance counters, and while this sounds quite easy, I couldn’t find a simple method because:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;ESX doesn’t seem to support an SNMP trap to report on VMFS volume capacity/free space. You could write a shell script and add a cron job on the Linux ESX service console, but this would be targeted at each ESX server, and the results would then be duplicated (and wouldn't work with ESX 3i) &lt;/li&gt;&lt;li&gt;VirtualCenter doesn’t appear to support a custom alert based on storage usage, only storage transfer rates. &lt;/li&gt;&lt;li&gt;The ESX servers are only in OpsMgr as network devices, not true agents, so we can’t use WBEM or any other method to query directly. If the upcoming OpsMgr 2007 cross platform extensions work on ESX, this may be easier, although as with option 1 this would still return duplicate datastore information for each ESX server in a cluster and wouldn't work with ESX 3i) &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This left a few options to gather the data in OpsMgr: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Query the VMFS storage through the VI snap-in and a PowerShell Script. &lt;/li&gt;&lt;li&gt;Query the VC database directly for this information from a VBS or PowerShell script. &lt;/li&gt;&lt;li&gt;Create a DTS job on the VC SQL server to extract the data to a suitable format. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Options two and three above would not be supported by VMware and may change as the database structure changes between VC versions.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Solution&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;Querying the VMFS storage from PowerShell and collect the information with VBScript, which includes: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;The PowerShell script using the VI snap-in to extract the datastore information &lt;/li&gt;&lt;li&gt;The VBScript to gather the information as performance data in Operations Manager 2007 &lt;/li&gt;&lt;li&gt;A trigger to execute the powershell script and put the data in a file to be gathered. &lt;/li&gt;&lt;li&gt;Rules in OpsMgr to gather the data using the type 'Script (Performance)'. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Steps taken: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Install the VMware VI PowerShell snap-in to your Virtual Centre box (you may need to install PowerShell first). VMware-Vim4PS-1.0.0-113525.exe is the binary I used. &lt;/li&gt;&lt;li&gt;Create an AD group and user for rights to VC. Add the user to the group. &lt;/li&gt;&lt;li&gt;Set rights in VirtualCenter to allow the group read-only rights at the root. This should be more granular if possible. &lt;/li&gt;&lt;li&gt;Add a recurring trigger on your VC box to run the PowerShell script to extract the information. Eg, this could be a scheduled task that runs a batch file or directly executes:&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;powershell . ".\PerfGatherVMwareDSSpace.ps1" &lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Create two rules in Operations Manager, Script (Performance) to gather the daily log file and store in the database as performance data. One rule is for the free space, another is for the free space as a percentage of the capacity. See the performance mapper notes below.&lt;br /&gt;&lt;ol type="disc"&gt;&lt;li&gt;The rules were created under ‘Windows Server 2003 Computer’, not enabled by default and overridden for the VC server (where the powershell script runs). You may want to target the rule differently, depending on your environment.&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;Create a performance view, showing performance data collected by the two rules above. &lt;/li&gt;&lt;li&gt;Create a monitor, using the LogicalDisk ‘% Disk Free’ object and counter to monitor on a threshold of 10%. Similarly, the monitor could be created under ‘Windows Server 2003 Computer’, not enabled by default and overridden for the VC server. The alert contains the following information: &lt;/li&gt;&lt;ol type="disc"&gt;&lt;li&gt;Object: $Data/Context/ObjectName$, Counter: $Data/Context/CounterName$, Instance: $Data/Context/InstanceName$, Value: $Data/Context/Value$ &lt;/li&gt;&lt;/ol&gt;&lt;/ol&gt;&lt;p&gt;Note that when using the script performance data provider, the ‘Performance Mapper’ tab is used to map the data returned by the script to the database. To make this generic, both the instance name and the value are used from each element: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;Object: LogicalDisk &lt;/li&gt;&lt;li&gt;Counter: Free Megabytes &lt;/li&gt;&lt;li&gt;Instance: $Data/Property/@Name$ &lt;/li&gt;&lt;li&gt;Value: $Data/Property[@Name]$ &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Note that the VBScript creates three typed ‘property bags’ and returns all. This results in a single XML that contains three dataitem elements, one for each instance. Creating a single property bag and adding the three instances results in only the first being processed.&lt;br /&gt;&lt;br /&gt;This should now gather free space in MB and as a percentage of the size for all VMFS datastores your VC server knows about, visible through the performance view, and alerted on when free space is less than 10% of the capacity for each volume.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL Queries&lt;/strong&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Some SQL queries against the OperationsManagerDW database I used along the way to query from the datawarehouse that the data was being gathered. Note that where I've specified 'datastore%' as a filter, you'll need to change this to the prefix of your datastores, eg ds01, ds02 would be ds%.&lt;br /&gt;&lt;br /&gt;&lt;pre class='mycode'&gt;&lt;code&gt;/*Return the raw performance data collected for the datastore* instances: */&lt;br /&gt;&lt;br /&gt;select DateAdd(Hour, 10, DateTime) as DateTime, InstanceName, SampleValue from perf.vperfRaw&lt;br /&gt;inner join vPerformanceRuleInstance on perf.vperfRaw.PerformanceRuleInstanceRowID = vPerformanceRuleInstance.PerformanceRuleInstanceRowID&lt;br /&gt;where InstanceName like 'datastore%'&lt;br /&gt;order by datetime desc&lt;br /&gt;&lt;br /&gt;/* Find new rules: */&lt;br /&gt;select top 10 * from dbo.vPerformanceRuleInstance&lt;br /&gt;where instancename like 'datastore%'&lt;br /&gt;order by performanceruleinstancerowid desc&lt;br /&gt;&lt;br /&gt;/* Find new raw performance data: */&lt;br /&gt;&lt;br /&gt;select top 100 DateTime, SampleValue, ObjectName, CounterName, FullName, Path, Name, DisplayName, ManagedEntityDefaultName from perf.vperfraw&lt;br /&gt;inner join vPerformanceRule on perf.vperfraw.PerformanceRuleInstanceRowID = vPerformanceRule.RulerowID&lt;br /&gt;inner join vManagedEntity on perf.vperfraw.ManagedEntityRowID = vManagedEntity.ManagedEntityRowID&lt;br /&gt;order by datetime desc&lt;br /&gt;&lt;br /&gt;/* Find new rule instances that have been created: */&lt;br /&gt;&lt;br /&gt;select top 10 * from dbo.vPerformanceRuleInstance&lt;br /&gt;order by performanceruleinstancerowid desc&lt;/span&gt;&lt;br /&gt;--&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;#PowerShell Script - PerfGatherVMwareDSSpace.ps1&lt;br /&gt;# Note that this includes a context to connect to VC, with hardcoded username and password.  You could avoid this by running the scheduled task under the security context you created with inherent rights to VC, and then remove the explicit -credential argument to Connect-VIServer.&lt;br /&gt;&lt;br /&gt;$ErrorActionPreference = "SilentlyContinue"&lt;br /&gt;add-pssnapin VMware.VimAutomation.Core&lt;br /&gt;&lt;br /&gt;$ADMINLOG = "c:\admin\logs"&lt;br /&gt;$outputFile = ""&lt;br /&gt;$today = [DateTime]::Now.ToString("yyyyMMdd")&lt;br /&gt;&lt;br /&gt;$scriptName = $MyInvocation.MyCommand.Name&lt;br /&gt;$scriptName = $scriptname.substring(0, $scriptname.LastIndexOf("."))&lt;br /&gt;&lt;br /&gt;if ($env:adminlog -ne $null) {        # Was there an adminlog environment variable?&lt;br /&gt;    $outputFile = $env:adminlog&lt;br /&gt;} else {&lt;br /&gt;   $outputFile = $ADMINLOG        # No, use the constant default  &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$outputFile += "\" + $scriptname + "_" + $today + ".csv"    # Construct the full path to the output file &lt;br /&gt;&lt;br /&gt;$server = "vc01"          # VC instance&lt;br /&gt;$username = "domain\user"        # Hardcoding is bad, but at least this is a RO account.&lt;br /&gt;$password = "password"&lt;br /&gt;&lt;br /&gt;$pwd = convertto-securestring $password -asplaintext -force&lt;br /&gt;&lt;br /&gt;$cred = New-Object Management.Automation.PSCredential ($username, $pwd)   # Create the credentials to use with the VC connection&lt;br /&gt;&lt;br /&gt;$vmserver = &amp; { trap {continue}; Connect-VIServer -server $server -Credential $cred } # Connect to VC, trapping the error&lt;br /&gt;&lt;br /&gt;if ($vmserver -is [System.Object]) {       # Do we have a connection?&lt;br /&gt;    Get-Datastore -server $vmserver | export-csv -noTypeInformation -path $outputFile # Yes, get the datastore details and store as CSV&lt;br /&gt;    if (test-path -path $outputFile) {&lt;br /&gt;        write-output "Datastore details exported to $outputFile"&lt;br /&gt;    } else {&lt;br /&gt;        write-output "Error: Datastore details were not exported to $outputFile"&lt;br /&gt;    }&lt;br /&gt;    $vmserver = $null&lt;br /&gt;} else {&lt;br /&gt;    write-output "Could not connect to $server"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;' VBScript&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;' Parse a CSV file containing the VMware volume information, and return the specified field from the data file or the calculated percent free&lt;br /&gt;&lt;br /&gt;Const TOKEN_DATE = "%date%"&lt;br /&gt;Dim SOURCE_FILE : SOURCE_FILE = "c:\admin\logs\PerfGatherVMwareDSSpace_" &amp; TOKEN_DATE &amp; ".csv"  ' Today's log file exported from the PowerShell VI-snapin script&lt;br /&gt;&lt;br /&gt;Const DELIMITER = ","           ' CSV data file&lt;br /&gt;Const ForReading = 1&lt;br /&gt;Const DISKTYPE_VMFS = "VMFS"          ' We're interested only in lines with VMFS volumes&lt;br /&gt;&lt;br /&gt;Const QUERY_SIZE = "Size"&lt;br /&gt;Const QUERY_FREE = "Free"&lt;br /&gt;QUERY_PERCENT = "Percent"&lt;br /&gt;&lt;br /&gt;Dim QUERY_DEFAULT : QUERY_DEFAULT = QUERY_FREE &lt;br /&gt;&lt;br /&gt;Const FIELD_SIZE = 1           ' The field in the CSV that contains the capacity of the VMFS volume&lt;br /&gt;Const FIELD_FREE = 0           ' The field in the CSV that contains the free disk space on the VMFS volume&lt;br /&gt;Const FIELD_PERCENT = 2&lt;br /&gt;&lt;br /&gt;Const PerfDataType  = 2&lt;br /&gt;&lt;br /&gt;Set oFSO = CreateObject("Scripting.FileSystemObject")&lt;br /&gt;&lt;br /&gt;Main()&lt;br /&gt;&lt;br /&gt;wscript.quit(0)&lt;br /&gt;&lt;br /&gt;Sub Main()&lt;br /&gt;&lt;br /&gt; If WScript.Arguments.UnNamed.Count &gt;= 1 Then&lt;br /&gt;  strQueryType = WScript.Arguments.UnNamed(0)&lt;br /&gt;  wscript.echo "Command-line argument passed, querying for " &amp; strQueryType&lt;br /&gt; Else&lt;br /&gt;  strQueryType = QUERY_DEFAULT&lt;br /&gt;  wscript.echo "No command-line argument passed, querying for the default of " &amp; strQueryType&lt;br /&gt; End if&lt;br /&gt;&lt;br /&gt; Select Case strQueryType&lt;br /&gt;  Case QUERY_SIZE  strField = FIELD_SIZE &lt;br /&gt;  Case QUERY_FREE  strField = FIELD_FREE&lt;br /&gt;  Case QUERY_PERCENT strField = QUERY_PERCENT&lt;br /&gt;  Case Else  strField = FIELD_FREE&lt;br /&gt; End Select&lt;br /&gt;&lt;br /&gt; dtmDate = Now &lt;br /&gt; strToday = DatePart("yyyy", dtmDate)         ' YYYY&lt;br /&gt; strToday = strToday &amp; String(2 - Len(DatePart("m", dtmDate)),"0") &amp; DatePart("m", dtmDate) ' MM&lt;br /&gt; strToday = strToday &amp; String(2 - Len(DatePart("d", dtmDate)),"0") &amp; DatePart("d", dtmDate) ' DD&lt;br /&gt;&lt;br /&gt; strDataFile = Replace(SOURCE_FILE, TOKEN_DATE, strToday)     ' Build the path to the data file&lt;br /&gt; wscript.echo "Looking for " &amp; strDataFile&lt;br /&gt;&lt;br /&gt; Dim oAPI, oBag&lt;br /&gt; Set oAPI = CreateObject("MOM.ScriptAPI")&lt;br /&gt;&lt;br /&gt; If oFSO.FileExists(strDataFile) Then        ' Does the data file exist for today?&lt;br /&gt;  WScript.Echo "Log file found, continuing"&lt;br /&gt;  Call ReadFile(strDataFile, strBuffer)       ' Yes, read the contents of the file into the buffer&lt;br /&gt;&lt;br /&gt;  For Each strLine in Split(strBuffer, vbCRLF)      ' For each line&lt;br /&gt;   arrEntry = Split(strLine, DELIMITER)      ' Split the line into an array on comma&lt;br /&gt;   If UBound(arrEntry) = 5 Then       ' Did this line have a valid number of fields?&lt;br /&gt;    If strComp(arrEntry(3), DISKTYPE_VMFS) = 0 Then    ' Yes, is it a VMFS volume? (excludes the header)&lt;br /&gt;    wscript.echo "Processing " &amp; strLine&lt;br /&gt;     If IsNumeric(arrEntry(FIELD_FREE)) AND IsNumeric(arrEntry(FIELD_SIZE)) Then     ' Yes, is the field we're after a numeric?&lt;br /&gt;      Set oBag = oAPI.CreateTypedPropertyBag(PerfDataType)  Create a typed name/value pair property bag&lt;br /&gt;&lt;br /&gt;      If (strField = FIELD_SIZE) OR (strField = FIELD_FREE ) Then&lt;br /&gt;       Call oBag.AddValue(arrEntry(5),CLng(arrEntry(strField))) ' Yes, convert to a long and add to the bag&lt;br /&gt;      ElseIf strField = QUERY_PERCENT Then&lt;br /&gt;       dblFreePercent = CDbl(arrEntry(FIELD_FREE) / arrEntry(FIELD_SIZE)*100)&lt;br /&gt;       Call oBag.AddValue(arrEntry(5), Round(dblFreePercent, 2))&lt;br /&gt;      End If&lt;br /&gt;      oAPI.AddItem(oBag)     ' Add the item to the bag (doing it here results in three datatime elements)&lt;br /&gt;&lt;br /&gt;     End If  &lt;br /&gt;    End If&lt;br /&gt;   End If&lt;br /&gt;  Next&lt;br /&gt;&lt;br /&gt; Else&lt;br /&gt;  WScript.Echo "Error: Daily data file not found - " &amp; strDataFile &lt;br /&gt;&lt;br /&gt; End If&lt;br /&gt;&lt;br /&gt; Call oAPI.ReturnItems &lt;br /&gt;&lt;br /&gt;End Sub    &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;'********************************************************&lt;br /&gt;' Purpose: Read a file and store the contents in the buffer&lt;br /&gt;' Assumptions: oFSO exists&lt;br /&gt;'              strLogFile contains the path/filename of the file to operate on&lt;br /&gt;' Effects: strBuffer is by reference&lt;br /&gt;' Inputs: strFileName, Path and filename of the source file&lt;br /&gt;'   strBuffer, the buffer used to store the contents of the file&lt;br /&gt;' Returns: None&lt;br /&gt;'&lt;br /&gt;'********************************************************&lt;br /&gt;Sub ReadFile (ByVal strFileName, ByRef strBuffer)   &lt;br /&gt; On Error Resume Next&lt;br /&gt; Dim objTextStream&lt;br /&gt;&lt;br /&gt; If Not oFSO.FileExists(strFileName) Then&lt;br /&gt;  WScript.Echo "Error: " &amp; strFileName &amp; " file not found."&lt;br /&gt;  Exit Sub&lt;br /&gt; End If&lt;br /&gt;    Set objTextStream = oFSO.OpenTextFile(strFileName, ForReading)&lt;br /&gt; strBuffer = objTextStream.ReadAll&lt;br /&gt;End Sub&lt;br /&gt;&lt;br /&gt;'------&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;How to Create a Probe-Based Performance Collection Rule in Operations Manager 2007&lt;br /&gt;&lt;a href="http://technet.microsoft.com/en-us/library/bb381406.aspx"&gt;http://technet.microsoft.com/en-us/library/bb381406.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;MOMScriptAPI.CreatePropertyBag Method&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb437556.aspx"&gt;http://msdn.microsoft.com/en-us/library/bb437556.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;XPath Examples:&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms256086(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms256086(VS.85).aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/mariussutara/archive/2008/01/24/momscriptapi-createtypedpropertybag-method.aspx"&gt;http://blogs.msdn.com/mariussutara/archive/2008/01/24/momscriptapi-createtypedpropertybag-method.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.technet.com/kevinholman/archive/2008/07/02/collecting-and-monitoring-information-from-wmi-as-performance-data.aspx"&gt;http://blogs.technet.com/kevinholman/archive/2008/07/02/collecting-and-monitoring-information-from-wmi-as-performance-data.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.afinn.net/2008/07/collecting-performance-data-in-operations-manager-2007-and-publishing-to-sharepoint-part-1/"&gt;http://www.afinn.net/2008/07/collecting-performance-data-in-operations-manager-2007-and-publishing-to-sharepoint-part-1/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.msdn.com/mariussutara/archive/2007/11/13/alert-description-and-parameter-replacement.aspx"&gt;http://blogs.msdn.com/mariussutara/archive/2007/11/13/alert-description-and-parameter-replacement.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8243600655559478734?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8243600655559478734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8243600655559478734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8243600655559478734'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/11/opsmgr-2007-performance-script-for.html' title='OpsMgr 2007 performance script - VMware datastores'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-2716690332256200009</id><published>2008-11-01T22:46:00.003+10:00</published><updated>2008-12-23T23:02:29.991+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Enumerating URLs in Internet Explorer</title><content type='html'>Have you ever wanted to get a list of the URLs you are currently browsing in Internet Explorer?  Probably not, but occasionally I've got a large number of IE windows open and I realise I need to close them all, but I would like to know the pages I'm in the middle of browsing.&lt;br /&gt;&lt;br /&gt;The PowerShell and VBScripts below do just that - enumerate the current iexplore.exe windows, and report the URL and name of any identified iexplore.exe windows.&lt;br /&gt;&lt;br /&gt;This is also good for gathering references, if you've got many pages open and you'd like to record the URLs for later reference, I find this script easier than repeated copy/paste.&lt;br /&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;# PowerShell&lt;br /&gt;&lt;br /&gt;$shell = new-object –com Shell.Application&lt;br /&gt;&lt;br /&gt;$windows = $shell.Windows()&lt;br /&gt;&lt;br /&gt;write-output ($windows.count.ToString() + " windows found")&lt;br /&gt;foreach ($window in $windows) {&lt;br /&gt;  if ($window.FullName -like "*iexplore*") {&lt;br /&gt;    write-output ($window.LocationURL + ", " + $window.LocationName)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;$shell = $null&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;' VBScript&lt;br /&gt;' Find the URLs of the currently running Internext Explorer Windows&lt;br /&gt;&lt;br /&gt;' References:&lt;br /&gt;'  http://windowssdk.msdn.microsoft.com/en-us/library/ms630310.aspx&lt;br /&gt;'  http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/objects/internetexplorer.asp&lt;br /&gt;&lt;br /&gt;Const IE_EXE = "iexplore.exe"&lt;br /&gt;&lt;br /&gt;Call FindCurrentURLs(strURLSet)&lt;br /&gt;WScript.Echo strURLSet&lt;br /&gt;&lt;br /&gt;wscript.quit(0)&lt;br /&gt;&lt;br /&gt;Function FindCurrentURLs(ByRef strURLSet)&lt;br /&gt; Dim objShell, objWindowSet, objWindow&lt;br /&gt; Dim strwindowName, strURL, strFullName&lt;br /&gt;&lt;br /&gt; Set objShell = CreateObject("Shell.Application")    ' Create a Windows shell automation object&lt;br /&gt; Set objWindowSet = objShell.Windows      ' Get the collection of open windows belonging to the shell&lt;br /&gt;&lt;br /&gt; Wscript.Echo "Processing " &amp; objWindowSet.Count &amp; " windows"   ' Report how many instances were found&lt;br /&gt;&lt;br /&gt; For Each objWindow in objWindowSet      ' For each InternetExplorer object in the ShellWindows set&lt;br /&gt;  strFullName = objWindow.FullName     ' Get the full path and executable of this window&lt;br /&gt;  If InStr(1, strFullName, IE_EXE, 1) &lt;&gt; 0 Then    ' Is this an IE shell object?&lt;br /&gt;   strURL = objWindow.LocationURL     ' Get the URL&lt;br /&gt;&lt;br /&gt;   If strURL &lt;&gt; "" Then &lt;br /&gt;    strURLSet = strURLSet &amp; vbCRLF &amp; strURL   ' Append to the set of URLs&lt;br /&gt;   End If&lt;br /&gt;  Else         ' No, probably explorer.exe skip&lt;br /&gt;   WScript.Echo "Skipped " &amp; strFullName &amp; " - not IE"&lt;br /&gt;  End If&lt;br /&gt; Next&lt;br /&gt;&lt;br /&gt; If Len(strURLSet) &gt;= Len(vbCRLF) Then strURLSet = Right(strURLSet, Len(strURLSet) - Len(vbCRLF)) ' Strip the leading vbCRLF&lt;br /&gt; &lt;br /&gt; Set objShell = Nothing&lt;br /&gt; Set objWindowSet = Nothing : Set objWindow = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-2716690332256200009?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=2716690332256200009' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/2716690332256200009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/2716690332256200009'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/11/enumerating-urls-in-internet-explorer.html' title='Enumerating URLs in Internet Explorer'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4381799541091866047</id><published>2008-10-26T10:00:00.003+10:00</published><updated>2008-10-26T10:10:23.627+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Active Directory'/><title type='text'>NTLM Trusts between 2003 and NT4</title><content type='html'>This post includes a few notes and example on an NTLM trust between two domains in a scenario I was working on - creating a trust between a 2003 user domin and an NT4 resource domain.&lt;br /&gt;&lt;br /&gt;I realise NT4 was a long time ago, but NT 4.0 was one end of a trust I set up earlier this year (2008), so other people might be in a similar situation. Note that to have a forest trust - even if it's only a one way trust - both the domain and the forest have to be in Windows 2003 functional mode, so whenever you're talking about trusts between external domains/forests, if one side is NT4 or 2000 then it's an NTLM trust.&lt;br /&gt;&lt;br /&gt;The types of access through the trust that will need to be considered: &lt;br /&gt;&lt;ul&gt;&lt;li&gt;Cross-domain resource access, including pass-through authentication, Trusted Client-&gt;Trusting Server-&gt;Trusting DC-&gt;Trusted DC&lt;/li&gt;&lt;li&gt;Authenticating access requests for a cross-domain object, Trusting DC -&gt; Trusted DC &lt;/li&gt;&lt;li&gt;Using the object picker and retrieving a list of trusted domains and trusted accounts also results in PDC-&gt;PDC communication between trusting and trusted. &lt;/li&gt;&lt;li&gt;Establishing the trust, the PDC of the trusting NT4 domain will try and resolve and then query the PDC of the trusted domain. TCP and NetBIOS sessions will be established, with named pipes, SMB and RPC. A combination of LSA RPC and Netlogon RPC &lt;/li&gt;&lt;li&gt;Sometimes there may be a need to control the DC Locator process on the NT4 DCs to ensure that only the single DC is contacted to authenticate cross-domain access requests. This will be a local lmhosts #PRE #DOM: entry, or a static WINS record, but this would only work when controlling authentication, some other operations require PDC emulator connectivity. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;How pass-through authentication across domains between 2003 and NT4 typically works: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Client from 2003 sends a request to the resource server in the NT4 domain &lt;/li&gt;&lt;li&gt;NT4 resource domain server passes the request to a NT4 DC in the local trusting domain &lt;/li&gt;&lt;li&gt;The NT4 DC checks the request is from a trusted domain, then establishes NetBIOS/SMB sessions with a DC in the trusted domain &lt;/li&gt;&lt;li&gt;Netr netlogon RPCs to create a secure channel and authenticate the samlogon request &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you need network security between the trusts, I recommend this be completed in a lab first. Otherwise you will probably end up with the connection between here and there looking like swiss cheese, or at the very least having larger holes than really required. VMware is great for creating a test-lab for this type of exercise, you could reproduce your existing production configuration and monitor the traffic going between various locations - this also requires something of a test network though.&lt;br /&gt;&lt;br /&gt;Note that this information can also be used in concert with the 'Replica Domain for Authentication' post to create a trust with a replica of your production domain, reducing the risk of exposing your domain.&lt;br /&gt;&lt;br /&gt;Both the RPC and SMB will be over NetBIOS when coming from NT4:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;nbname 137/UDP&lt;br /&gt;nbname 137/TCP&lt;br /&gt;nbdatagram&lt;br /&gt;138/UDP&lt;br /&gt;nbsession 139/TCP&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/span&gt;In the scenario I was working on, the applications in the resource domain were either accessed via windows authenticated HTTP or direct SQL connectivity. Two examples below show the conversation in authenticating over the trust, between an XP member of the 2003 domain to a member server in the NT4 domain.&lt;br /&gt;&lt;br /&gt;Assuming there’s a 2003 member server running IIS using windows authentication in the NT 4.0 resource domain, and XP clients from the corporate forest are accessing the application directly: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;Internet Explorer from the workstation initiates a HTTP session with the web server &lt;/li&gt;&lt;li&gt;HTTP 401 is returned by the web server, indicating that authentication is required, with the WWW-Authenticate response headers indicating Negotiate and NTLM are the available schemes. &lt;/li&gt;&lt;li&gt;NTLM Negotiate (0x00000001) is then sent from the client to the server indicating supported NTLM options &lt;/li&gt;&lt;li&gt;The web server responds with a challenge message (0x00000002) for the client to prove their identity &lt;/li&gt;&lt;li&gt;The workstation responds with an authenticate message (0x00000003) – an encrypted challenge response based on the logged on users’ password hash &lt;/li&gt;&lt;li&gt;A Netlogon RPC call is initiated from the web server to the NT 4.0 DC the server has its secure channel with to initiate the samlogon request, providing the username, domain name, challenge, and challenge-response. &lt;/li&gt;&lt;li&gt;The NT 4.0 DC checks the information and determines that it has a trust with the named domain. &lt;/li&gt;&lt;li&gt;The NT 4.0 DC establishes a secure channel with the trusted replica domain (or uses the existing channel) &lt;/li&gt;&lt;li&gt;A second Netlogon RPC call is then passed through to the replica 2003 domain using the same information as the first call (wrapped in NetBIOS in this case) &lt;/li&gt;&lt;li&gt;The replica DC retrieves the hash of the specified user’s password, the original challenge is then encrypted using this hash and compared to the challenge-response provided with the request. &lt;/li&gt;&lt;li&gt;Assuming passwords are synchronised, the hashes match and the trusted netlogon call is successful &lt;/li&gt;&lt;li&gt;The Netlogon call from the web server is also returned as successful &lt;/li&gt;&lt;li&gt;The web page is served to the XP workstation &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Connecting across domains to SQL in NT4 from an XP workstation in 2003: &lt;/p&gt;&lt;ol&gt;&lt;li&gt;The user starts the local MDE (which has an embedded connection to remote SQL) &lt;/li&gt;&lt;li&gt;The workstation initiates a connection over TCP 1433 to the SQL server &lt;/li&gt;&lt;li&gt;The workstation tries to verify the name/IP of the SQL server, with a reverse lookup DNS query and a NetBIOS Adapter Status Request to the IP over UDP 137 NBNS. &lt;/li&gt;&lt;li&gt;The local Active Directory KDS is queried to see if there is a matching SPN for the requested SQL service. This is unsuccessful and the authentication protocol falls back to NTLM. &lt;/li&gt;&lt;li&gt;A TDS NTLMSSP challenge/response occurs between the workstation and the cross-domain SQL server, including:&lt;br /&gt;a. The negotiate response from the workstation contains the client name and the database (0x1)&lt;br /&gt;b. The NT4 challenge from the SQL server (0x2)&lt;br /&gt;c. The authenticate response messages, containing response to the challenge using the currently logged in credentials (of the XP workstation) &lt;/li&gt;&lt;li&gt;A Netlogon RPC call is initiated from the SQL server to the NT4 DC the server has its secure channel with to initiate the samlogon request, providing the username, challenge, and challenge-response. &lt;/li&gt;&lt;li&gt;The NT4 DC checks the information and determines that it has a trust with the named domain (the 2003 user domain) &lt;/li&gt;&lt;li&gt;The NT4 DC establishes a secure channel with the trusted domain &lt;/li&gt;&lt;li&gt;A second Netlogon RPC call is then passed through to a trusted DC using the same information as the first call &lt;/li&gt;&lt;li&gt;The NT4 DC retrieves the hash of the specified user’s password, the original challenge is then encrypted using this hash and compared to the hash provided with the request. &lt;/li&gt;&lt;li&gt;Assuming the password is correct, the hashes match and the trusted netlogon call is successful across the trust. &lt;/li&gt;&lt;li&gt;The Netlogon call between workstation SQL server is also returned as successful &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;References&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Replica Domain for Authentication&lt;br /&gt;&lt;/span&gt;&lt;a href="http://waynes-world-it.blogspot.com/2008/08/replica-domain-for-authentication.html"&gt;&lt;span style="font-size:85%;"&gt;http://waynes-world-it.blogspot.com/2008/08/replica-domain-for-authentication.html&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;How Domain and Forest Trusts Work&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/f5c70774-25cd-4481-8b7a-3d65c86e69b11033.mspx?mfr=true"&gt;&lt;span style="font-size:85%;"&gt;http://technet2.microsoft.com/windowsserver/en/library/f5c70774-25cd-4481-8b7a-3d65c86e69b11033.mspx?mfr=true&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Trust Technologies&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/9d688a18-15c7-4d4e-9d34-7a763baa50a11033.mspx?mfr=true"&gt;&lt;span style="font-size:85%;"&gt;http://technet2.microsoft.com/windowsserver/en/library/9d688a18-15c7-4d4e-9d34-7a763baa50a11033.mspx?mfr=true&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Establishing Trust Relationships&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.microsoft.com/technet/archive/winntas/plan/capacityplanning/a03_trst.mspx?mfr=true"&gt;&lt;span style="font-size:85%;"&gt;http://www.microsoft.com/technet/archive/winntas/plan/capacityplanning/a03_trst.mspx?mfr=true&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;NTLM user authentication in Windows&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/102716"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/102716&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Direct hosting of SMB over TCP/IP&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/KB/204279"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/KB/204279&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;How to configure a firewall for domains and trusts&lt;br /&gt;&lt;/span&gt;&lt;a href="http://support.microsoft.com/kb/179442"&gt;&lt;span style="font-size:85%;"&gt;http://support.microsoft.com/kb/179442&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Windows NT 4.0 tries to resolve manually-typed names by contacting the PDC for the remote user's domain (UDP 138). If that communication fails, a Windows NT 4.0-based computer contacts its own PDC, and then asks for resolution of the name. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Describes some of the network traffic between 2003 trusts, including methods of setting the LSA and Network RPC ports used for various operations.&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/108124dd-31b1-4c2c-9421-6adbc1ebceca1033.mspx?mfr=true"&gt;&lt;span style="font-size:85%;"&gt;http://technet2.microsoft.com/windowsserver/en/library/108124dd-31b1-4c2c-9421-6adbc1ebceca1033.mspx?mfr=true&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;I've also used this document in the past, touching on some topics such as DNS, netlogon optimisation/site synchronisation&lt;br /&gt;&lt;/span&gt;&lt;a href="http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/directory/activedirectory/mtfstwp.mspx"&gt;&lt;span style="font-size:85%;"&gt;http://www.microsoft.com/technet/prodtechnol/windowsserver2003/technologies/directory/activedirectory/mtfstwp.mspx&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Forest trust information – the flow and types of traffic for cross-forest authentication, which shows the workstation from the account domain (trusted), contacting a KDC in the resource domain (trusting) for kerberos authentication, often overlooked - this means traffic goes directly from all workstation endpoints to DCs in the resource domain, as opposed to an NTLM trust where DCs normally talk to each other)&lt;br /&gt;&lt;/span&gt;&lt;a href="http://technet2.microsoft.com/windowsserver/en/library/517b4fa4-5266-419c-9791-6fb56fabb85e1033.mspx?mfr=true"&gt;&lt;span style="font-size:85%;"&gt;http://technet2.microsoft.com/windowsserver/en/library/517b4fa4-5266-419c-9791-6fb56fabb85e1033.mspx?mfr=true&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size:85%;"&gt; &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4381799541091866047?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4381799541091866047' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4381799541091866047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4381799541091866047'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/10/ntlm-trusts-between-2003-and-nt4.html' title='NTLM Trusts between 2003 and NT4'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-167204808348889340</id><published>2008-10-21T23:19:00.003+10:00</published><updated>2008-10-26T15:16:55.540+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Server'/><category scheme='http://www.blogger.com/atom/ns#' term='Automation'/><title type='text'>2003 Servers with Hibernation enabled</title><content type='html'>How many of your 2003 servers have hibernation enabled and you never realised? If you're like me, possibly a few, and I can't think of a scenario where I would want to hibernate a server.&lt;br /&gt;&lt;br /&gt;This post provides a simple method of detecting whether hibernation is enabled, and then a command to remotely disable hibernation on each server. It works based on the premise that if hibernation is enabled, you'll have a file called hiberfil.sys on the root of your system drive.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Create a text file called servers.txt listing one server per-line and then run the following command &lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (servers.txt) do @if exist \\%~i\c$\hiberfil.sys (echo %~i,Enabled) else (echo %~i,Disabled)&lt;/span&gt; &lt;/li&gt;&lt;li&gt;Save the output filterd by Disabled (find /i "Disabled" results.txt) and run the following command to disable on each (assuming you have psexec) &lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (servers_hibernate.txt) do psexec \\%i powercfg /HIBERNATE off &lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;This should automatically delete the hibernation file, reclaiming the hard disk space equal to the RAM of the machine.&lt;br /&gt;&lt;br /&gt;Note that this assumes your systemdrive is C: and that you have administrative shares enabled (C$). To accurately distinguish between servers that don't have C:/C$. you could also run a nested if command (which assumes an installation directory of Windows):&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;for /f %i in (servers.txt) do @if exist \\%~i\c$\windows (if exist \\%~i\c$\hiberfil.sys (echo %~i,Enabled) else (echo %~i,Disabled)) else echo %~i,Not Found &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can also manually run the command to disable hibernation against one server:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;psexec \\%server% powercfg /HIBERNATE off &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-167204808348889340?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=167204808348889340' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/167204808348889340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/167204808348889340'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/10/2003-servers-with-hibernation-enabled.html' title='2003 Servers with Hibernation enabled'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8392734335984543272</id><published>2008-09-28T14:59:00.004+10:00</published><updated>2008-12-23T23:06:46.238+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scripting'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Reading Shortcuts with PowerShell and VBS</title><content type='html'>This post provides a simple method of enumerating shortcuts and retrieving their properties, either using PowerShell or VBScript.  There is nothing particularly clever here, but I had a need a while back to use the enumeration, and I wrote the simple powershell equivalent to see how easy it would be.  Note that I couldn't easily see a managed code .Net method to process shortcuts, so I fell back on the wscript COM object.  More than likely there is a better method (get it? :) than this.&lt;br /&gt;&lt;br /&gt;Run the scripts:&lt;br /&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;powershell . .\ReadShortcut.ps1 -p \\%server%\%share%\folder\path&lt;br /&gt;powershell . .\ReadShortcut.ps1 -f \\%server%\%share%\shortcut.lnk&lt;br /&gt;cscript //nologo "ReadShortcut.vbs" \\%server%\%share%\folder\path&lt;br /&gt;cscript //nologo "ReadShortcut.vbs" \\%server%\%share%\shortcut.lnk&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;param(&lt;br /&gt;   [string] $path = "",&lt;br /&gt;   [string] $file = ""&lt;br /&gt;   )&lt;br /&gt;&lt;br /&gt;$WshShell = new-object -comobject "WScript.Shell"       # Instantiate the wscript.shell COM object&lt;br /&gt;&lt;br /&gt;if ($path -ne "") {&lt;br /&gt;    $shortcuts = get-childitem -path $path -filter "*.lnk" -rec    # Find all .lnk files, recursing in to subdirectories&lt;br /&gt;    $shortcuts &amp;#124; foreach-object {$WshShell.CreateShortcut($_.FullName) }  # For each file, pass the fullname to the COM object to open the shortcut and enumerate the properties&lt;br /&gt;} elseif ($file -ne "") {&lt;br /&gt;    $shortcut = get-item -path $file       # Get the single file&lt;br /&gt;    if ($shortcut -ne $null) { $WshShell.CreateShortcut($shortcut) }   # If exists, read the shortcut properties&lt;br /&gt;} else {&lt;br /&gt;    write-output "No arguments specified, please use either -p to specify a path or -f for a specific .lnk file"&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;#-------#&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;'ReadShortcut.vbs&lt;br /&gt;' Read a shortcut or a top-level directory of shortcuts and write the properties to stdout&lt;br /&gt;If WScript.Arguments.UnNamed.Count = 1 Then&lt;br /&gt; strShortcut = WScript.Arguments.UnNamed(0)&lt;br /&gt;Else&lt;br /&gt; WScript.Echo "Please supply the name of an lnk file or directory to read, eg c:\test.lnk or c:\shortcuts"&lt;br /&gt; WScript.Quit(1)&lt;br /&gt;End If&lt;br /&gt;&lt;br /&gt;Set objFSO = CreateObject("Scripting.FileSystemObject")&lt;br /&gt;&lt;br /&gt;If objFSO.FolderExists(strShortCut) Then      ' Was a directory specified?&lt;br /&gt; Set objFolder = objFSO.getFolder(strShortcut)     ' Get the folder&lt;br /&gt; &lt;br /&gt; For Each objfile in objFolder.Files      ' For each file in the top-level directory&lt;br /&gt;  If objfile.type = "Shortcut" Then     ' Is this file a shortcut?&lt;br /&gt;   Call Readshortcut(objFile.Path, strProperties)   ' yes, read the properties&lt;br /&gt;   dtmCreationDate = objFile.DateCreated&lt;br /&gt;   WScript.Echo dtmCreationDate &amp; "," &amp; strProperties  ' output the results&lt;br /&gt;  End If &lt;br /&gt; Next&lt;br /&gt;ElseIf objFSO.FileExists(strShortCut) Then      ' Was an individual file specified?&lt;br /&gt; Call Readshortcut(strShortcut, strProperties)     ' read the properties of the file&lt;br /&gt; WScript.Echo strProperties       ' output the results&lt;br /&gt;Else           ' file-not-found&lt;br /&gt; WScript.Echo "Error: Could not read '" &amp; strShortcut &amp; "'"&lt;br /&gt; WScript.Quit(2)&lt;br /&gt;End If&lt;br /&gt;Set objFSO = Nothing&lt;br /&gt;&lt;br /&gt;Function Readshortcut(ByRef strShortcut, ByRef strProperties)&lt;br /&gt;&lt;br /&gt; set objWshShell = WScript.CreateObject("WScript.Shell")    ' Create the shell object&lt;br /&gt; set objShellLink = objWshShell.CreateShortcut(strShortcut)   ' Execute the createshortcut method, which also retrieves an existing shortcut&lt;br /&gt; strProperties = strShortCut &amp; "," &amp; objShellLink.TargetPath &amp; "," &amp; objShellLink.WindowStyle &amp; "," &amp; objShellLink.Hotkey &amp; "," &amp; objShellLink.IconLocation &amp; "," &amp; objShellLink.Description &amp; "," &amp; objShellLink.Arguments &amp; "," &amp; objShellLink.FullName &amp; "," &amp; objShellLink.WorkingDirectory &amp; """"&lt;br /&gt;&lt;br /&gt; ' This propertly can be set, but not read? - objShellLink.RelativePath&lt;br /&gt; Set objShellLink = Nothing&lt;br /&gt; Set objWshshell = Nothing&lt;br /&gt;End Function&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8392734335984543272?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8392734335984543272' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8392734335984543272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8392734335984543272'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/reading-shortcuts-with-powershell-and.html' title='Reading Shortcuts with PowerShell and VBS'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-6136752888332753735</id><published>2008-09-27T21:17:00.002+10:00</published><updated>2008-09-29T17:08:09.699+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Workstation'/><title type='text'>Modifying DLL Resources</title><content type='html'>While it wouldn't be supported by Microsoft, there are a few methods you can use to modify the resources contained in DLLs - usually useful if you would like to change how a window or dialog box is displayed. The easiest way I've seen is with a program called reshacker.exe.&lt;br /&gt;&lt;br /&gt;A practical example is when you might be trying to display a large legal notice text using the standard MS gina on XP - and you can't actually scroll down to view the whole message due to the lack of scroll bars in the legal notice text dialog box.&lt;br /&gt;&lt;br /&gt;To add a dialog box to this display in msgina.dll in a XP SP2 machine, you could:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use reshacker to open msgina.dll, and modify the dialog number 2500 - with 1033 language in my case (en-au) &lt;/li&gt;&lt;li&gt;Edit the control, allowing the WS_VSCROLL option&lt;/li&gt;&lt;li&gt;Recompile the script and save the new DLL. &lt;/li&gt;&lt;li&gt;You'll then either have to modify WFP behaviour, disable it, or to test this I overwrote the cached copy to fool Windows File Protection in system32\dllcache &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Any new logon through the interactive console or TS to a workstation with a legal notice text should display it in a dialog box with a scroll bar.&lt;br /&gt;&lt;br /&gt;Resource Hacker homepage:&lt;br /&gt;&lt;a href="http://angusj.com/resourcehacker/"&gt;http://angusj.com/resourcehacker/&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-6136752888332753735?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=6136752888332753735' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/6136752888332753735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/6136752888332753735'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/modifying-dll-resources.html' title='Modifying DLL Resources'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-7627171592464509194</id><published>2008-09-21T17:25:00.004+10:00</published><updated>2008-09-29T17:08:21.839+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Printing'/><title type='text'>Automatically mapping printers</title><content type='html'>A while back I came across one of the new 'features' in server 2003 R2, a method of centrally managing printers through the ‘Print Management’ snap-in, and then deploying those printers to workstations or users through a GPO.&lt;br /&gt;&lt;br /&gt;This sounds clever, but I believe it's really just an automated method of creating a computer startup/user logon script, which uses a control file to determine which printers are to be installed and then runs a commandline utility to install those printers (pushprinterconnections.exe).&lt;br /&gt;&lt;br /&gt;This made me reconsider the approach to managing printers for workstations, and similar or better functionality could be provided by one or more of the methods below:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use policy to deploy all printers for a building/floor/subnet to workstations. This would be the least management, but probably the least effective as there could be dozens or hundreds of printers per building/floor/subnet. &lt;/li&gt;&lt;li&gt;Have a startup script that automatically adds a default printer when a user first logs on. The default would have to be either based on AD subnets and a mapping file between these subnets and default printers, or possibly based on user information such as location and department, which would be used to query AD/printer names to map appropriate printers, eg a user location of 'Building 1/Floor 2' and department of 'Finance' for a user could easliy be translated to a printer called FINPRINT1 with an AD location of 'Building 1/Floor 2'. &lt;/li&gt;&lt;li&gt;Have a process that exports MAC/PCs connected per floor switch, which would be used as a control file to automatically map printers based on floor. This would typically require assistance from your friendly data communications team. &lt;/li&gt;&lt;li&gt;Use 'DHCP snooping' to further identify where clients are coming from. For example, DHCP relay agent option 82 can be used to insert the switch MAC address/subscriber VLAN/port, SNMP information to the DHCP request packet (when using layer 2 DHCP relay agents as opposed to layer 3 ip helpers). This information could potentially be parsed by the DHCP server to identify the switch/port clients are coming from by parsing the circuit-id/remote-id. The output could be used as a control file to automatically map printers based on floor. &lt;/li&gt;&lt;li&gt;Use the information from 4 and information on floor patching to construct a virtual map of your floors/buildings, which would place one or more workstations close to one or more printers, and map them automatically. &lt;/li&gt;&lt;li&gt;When you build each workstation (this wouldn't work for roaming devices), create a control file that indicates physically where this workstation is located using the Microsoft format for subnet locations, eg Building/Floor 1/West Corner/Pod 4. Populate printer locations to this degree, and then your logon script could search the AD for matching printers and map those that are closest. You could also use this information to create a shortcut called 'Find printers' that uses 'rundll32 dsquery,OpenSavedDsQuery %Config%.qds' to open a saved query file that you've populated with this location. You would then need processes in place to update this control file as the workstation moves, otherwise it becomes incorrect - worse than nothing at all. &lt;/li&gt;&lt;li&gt;Do nothing clever and let users add their own printers &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Of course the 'nothing clever' option normally wins out, but in a large organisation one of the options above could add real value, and if done correctly would not be high maintenance.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;br /&gt;Manage Printers with New Group Policy Features in Windows Server 2003 R2&lt;br /&gt;&lt;a href="http://www.microsoft.com/technet/technetmag/issues/2006/08/ManagePrinters/"&gt;http://www.microsoft.com/technet/technetmag/issues/2006/08/ManagePrinters/&lt;/a&gt; &lt;/p&gt;&lt;p&gt;RFC 3046 - DHCP Relay Agent Information Option&lt;br /&gt;&lt;a href="http://www.faqs.org/rfcs/rfc3046.html"&gt;http://www.faqs.org/rfcs/rfc3046.html&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Configuring the DHCP Option 82 for Subscriber Identification&lt;br /&gt;&lt;a href="http://www.cisco.com/en/US/docs/switches/lan/catalyst3550/software/release/12.1_13_ea1/configuration/guide/swdhcp82.html"&gt;http://www.cisco.com/en/US/docs/switches/lan/catalyst3550/software/release/12.1_13_ea1/configuration/guide/swdhcp82.html&lt;/a&gt; &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-7627171592464509194?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=7627171592464509194' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7627171592464509194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/7627171592464509194'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/automatically-mapping-printers.html' title='Automatically mapping printers'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-2315900462100261112</id><published>2008-09-13T20:27:00.003+10:00</published><updated>2008-12-24T12:10:24.684+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Security'/><category scheme='http://www.blogger.com/atom/ns#' term='PowerShell'/><title type='text'>Simple string encryption with PowerShell</title><content type='html'>While looking for a method to obfuscate passwords in script files, I started with securestring input combined with the convertfrom-securestring and convertto-securestring functions.  Unfortunately (or fortunately from a security perspective) the securestring seems relevant only for per session/user/process/computer (or a combination thereof).&lt;br /&gt;&lt;br /&gt;From documentation these functions use Rijndael symmetric encryption, so I modified another example for a very simple, key-less passphrase-less encryption/decryption of a string.  This isn’t even very good obfuscation, let alone encryption, but if you encrypted a password and then reproduce the last 10 lines to decrypt the encrypted string, it’s slightly better than storing passwords in very visible paintext (sort of).  I guess this could be obfuscated further by reading the encrypted string from a secured file or registry key.&lt;br /&gt;&lt;br /&gt;This could be made as complex as you like with keys and initialisation vectors, but unless you make people enter the key (and then why not just make them enter the password?), there would still be something in plaintext, so I didn’t think there was much point.&lt;br /&gt;&lt;br /&gt;I'm still undecided on whether there is any benefit with such simple obfuscation, but I thought I'd post the script nonetheless.&lt;br /&gt;&lt;span&gt;&lt;pre class='mycode'&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;$string = "LongStringToEncryptAsATest"&lt;br /&gt;$string&lt;br /&gt;&lt;br /&gt;$r = new-Object System.Security.Cryptography.RijndaelManaged  # use Rijndael symmetric key encryption&lt;br /&gt;$c = $r.CreateEncryptor((1..16), (1..16))    # Set the key and initialisation vector to 128-bytes each of (1..16)&lt;br /&gt;$ms = new-Object IO.MemoryStream&lt;br /&gt;$cs = new-Object Security.Cryptography.CryptoStream $ms,$c,"Write" # Target data stream, transformation, and mode&lt;br /&gt;$sw = new-Object IO.StreamWriter $cs&lt;br /&gt;$sw.Write($String)       # Write the string through the crypto stream into the memory stream&lt;br /&gt;$sw.Close()&lt;br /&gt;$cs.Close()&lt;br /&gt;$ms.Close()&lt;br /&gt;$r.Clear()&lt;br /&gt;[byte[]]$result = $ms.ToArray()      # Byte array from the encrypted memory stream&lt;br /&gt;$encstring = [Convert]::ToBase64String($result)    # Convert to base64 for transport&lt;br /&gt;&lt;br /&gt;$encstring         # The encrypted base64 string representation&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;$Encrypted = [Convert]::FromBase64String($encstring)   # Convert the encrypted string to a byte array&lt;br /&gt;$r = new-Object System.Security.Cryptography.RijndaelManaged  # use Rijndael symmetric key encryption&lt;br /&gt;$d = $r.CreateDecryptor((1..16), (1..16))    # Set the key and initialisation vector to 128-bytes each of (1..16)&lt;br /&gt;&lt;br /&gt;$ms = new-Object IO.MemoryStream @(,$Encrypted)    # Create a memorystream from a single-element name/value pair hash table of the byte array&lt;br /&gt;$cs = new-Object Security.Cryptography.CryptoStream $ms,$d,"Read" # Target data stream, transformation, and mode&lt;br /&gt;$sr = new-Object IO.StreamReader $cs     # Read the string through the crypto stream from the encrypted memory stream&lt;br /&gt;write-output $sr.ReadToEnd()      # Write the unencrypted string&lt;br /&gt;$sr.Close()&lt;br /&gt;$cs.Close()&lt;br /&gt;$ms.Close()&lt;br /&gt;$r.Clear()&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/span&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-2315900462100261112?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=2315900462100261112' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/2315900462100261112'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/2315900462100261112'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/simple-string-encryption-with.html' title='Simple string encryption with PowerShell'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-1055575373142513601</id><published>2008-09-08T21:42:00.002+10:00</published><updated>2008-09-29T17:08:46.218+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='NTFS'/><title type='text'>Useful NTFS and security command-line operations</title><content type='html'>The commands below are a subset of the complete command list found in &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;Useful command-lines&lt;/a&gt;, and provide different methods to query, modify and report on aspects of NTFS, including security, MFT, ABE, alternate data streams, security templates and SDDL.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disable path parsing to access a file using UNC&lt;/u&gt;&lt;br /&gt;type "\\?\UNC\server\share\path\file.txt"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Dump file and security attributes on an NTFS filesystem&lt;br /&gt;&lt;/u&gt;filestat %file%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show the ACL in SDDL format using cacls (2003) &lt;/u&gt;&lt;br /&gt;cacls c:\ /s&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add authenticated users:R to the root (not OICI) using SDDL with cacls&lt;br /&gt;&lt;/u&gt;cacls c:\ /S:"D:PAI(A;OICI;FA;;;BA)(A;;0x1200a9;;;AU)(A;OICI;FA;;;SY)"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query Storage Report Management global settings (file screening and quotas) &lt;/u&gt;&lt;br /&gt;reg query HKEY_LOCAL_MACHINE\Cluster\SRM\Settings\SrmGlobalSettings /v Data&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show the current mounted volumes on the local system&lt;br /&gt;&lt;/u&gt;mountvol OR mountvol c:\ /l&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a hardlink directory entry linking one file to another &lt;/u&gt;&lt;br /&gt;fsutil hardlink create %NewFileLink% %ExistingFile%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;create symbolic dir, file links, hard links and dir junctions Vista/2008&lt;br /&gt;&lt;/u&gt;mklink&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add a string to an alternate stream stored as a $DATA attribute &lt;/u&gt;&lt;br /&gt;echo this content will be stored in the file sub stream &gt; test.txt:stream1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add the contents of a file to an alternate data strem&lt;br /&gt;&lt;/u&gt;type file.txt &gt; test.txt:stream1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a new file in an alternate stream as part of a directory&lt;br /&gt;&lt;/u&gt;md test &amp;amp; echo alternate stream &gt; test:stream1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Display the stream &lt;/u&gt;&lt;br /&gt;more &lt;&gt; test:test.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run the executable in the alternate stream&lt;br /&gt;&lt;/u&gt;cmd /c start .\test:test.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Retrieve the binary file from an alternate data stream (port of Unix Cat)&lt;br /&gt;&lt;/u&gt;cat test:test.exe &gt; note.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remove an NTFS alternate data stream (does not maintain timestamps)&lt;br /&gt;&lt;/u&gt;type test.txt&gt;test1.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Delete an alternate data stream&lt;br /&gt;&lt;/u&gt;streams -d test.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Dump NTFS info from the MFT for a File Record Segment (unix port)&lt;br /&gt;&lt;/u&gt;ntfsinfo -d /dev/hda1 -i 36&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find cluster disk size and free space &lt;/u&gt;&lt;br /&gt;echo clusnode1 &gt; clusternodes.txt &amp;amp; echo clusnode2 &gt;&gt; clusternodes.txt &amp;amp; echo clusnode3 &gt;&gt; clusternodes.txt &amp;amp; echo clusnode4 &gt;&gt; clusternodes.txt &amp;amp; wmic /node:@clusternodes.txt path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET SystemName,Name,Size,FreeSpace,VolumeName&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a security template from the given directory for SDDL secedit processing&lt;br /&gt;&lt;/u&gt;for /d %i in (%source%\*.*) do @for /f "tokens=2" %j in ('cacls.exe %i /S') do @echo Processing %~ni &amp;amp; echo "%i",2,%j &gt;&gt; Security.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Make test directories from a security template &lt;/u&gt;&lt;br /&gt;for /f "tokens=1,2,3,* delims=\," %i in ('"find /i "dir1\dir2" template.inf"') do md "c:\temp\sectest\%j\%k&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reformat the target of a security template for offline testing&lt;br /&gt;&lt;/u&gt;for /f "tokens=1,2,3,* delims=\," %i in ('"find /i "dir1\dir2" template.inf"') do @echo "c:\temp\sectest\%j\%k,%l&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remotely configure filesystem NTFS security using a secedit template&lt;br /&gt;&lt;/u&gt;psexec \\%server% secedit /configure /db c:\windows\temp\%random%.sdb /cfg c:\windows\security\templates\%template%.inf /log c:\windows\temp\Configure.log&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disable automatic mounting of volumes added to a 2003 system&lt;br /&gt;&lt;/u&gt;automount disable&lt;br /&gt;&lt;u&gt;Remove automatic mount points for volumes that no longer exist&lt;/u&gt;&lt;br /&gt;automount scrub&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report the NTFS permissions for restore from a SDDL template&lt;br /&gt;&lt;/u&gt;setacl -on c:\windows -ot file -actn list -rec cont_obj -lst f:sddl -bckp test.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List the file system filters and instances installed on the system&lt;br /&gt;&lt;/u&gt;fltmc filters &amp;amp; fltmc instances&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run diskpart to list NTFS volumes remotely&lt;br /&gt;&lt;/u&gt;psexec \\%server% cmd /c "echo list volume diskpart find /i "NTFS""&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find local disks other than C: and D: that are NTFS&lt;br /&gt;&lt;/u&gt;wmic /node:"%server%" path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET SystemName,Name&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find local disks using powershell and output to CSV&lt;br /&gt;&lt;/u&gt;Get-WmiObject -Namespace root\cimv2 -ComputerName %server% -Query "SELECT * from Win32_LogicalDisk WHERE FileSystem='NTFS' AND Description = 'Local Fixed Disk' AND Name != 'C:' AND Name != 'D:'" export-csv c:\disk.csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Read directories from a security template, checking if they exist&lt;br /&gt;&lt;/u&gt;for /f "skip=2 tokens=1 delims=," %i in ('"find /i "OICI" \\%server%\%Template%"') do @if not exist \\%server%\%drive%$%~pi echo \\%server%\%drive%%~pi&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the NTFS attributes of a file &lt;/u&gt;&lt;br /&gt;nfi "C:\windows\system32\notepad.exe"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report and save the security on one or more NTFS Filesystem objects&lt;br /&gt;&lt;/u&gt;ICACLS %object% /save %outputfile%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reset the inherited DACL flag on an object to not protected, inherit below&lt;br /&gt;&lt;/u&gt;setacl -on %Directory% -ot file -actn setprot -op dacl:np&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reset inherited permissions for specified NTFS objects &lt;/u&gt;&lt;br /&gt;setacl -on %Directory%\*.* -ot file -actn rstchldrn -rst DACL&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check user home drive permissions from hmDir (top-level)&lt;br /&gt;&lt;/u&gt;for /f %i in (%users.txt%) do @for /f "tokens=*" %m in ('"dsquery user -name %i dsget user -hmdir find /i "%i""') do cacls "%m"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check Access Based Enumeration is enabled on a top-level share&lt;br /&gt;&lt;/u&gt;psexec \\%server% abecmd %share%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check permissions are being inherited &lt;/u&gt;&lt;br /&gt;for /f %i in (%users.txt%) do @for /f "tokens=1" %m in ('"dsquery user -name %i dsget user -hmdir find /i "%i""') do @for /d %p in (%m\*.*) do @echo cacls "%p"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check ownership of files&lt;br /&gt;&lt;/u&gt;for /f %i in (%users.txt%) do @for /f "tokens=1" %m in ('"dsquery user -name %i dsget user -hmdir find /i "%i""') do @dir %m /q/s&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Process robocopy /l output to find files/data that would be copied&lt;br /&gt;&lt;/u&gt;for /f "tokens=2,5 delims=_:" %i in (output.txt) do @If "!User!" NEQ "%i" (@Set User=%i&amp;amp;@Set Line=%i,%j) else (@Set Line=!Line!,%j &amp;amp; @Echo !Line!)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List ACLs in SDDL format &lt;/u&gt;&lt;br /&gt;setacl -on %filepath% -ot file -actn list -lst f:sddl&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Change the ownership of all subdirectories and files in a folder&lt;br /&gt;&lt;/u&gt;subinacl /subdirectorie %Path%\*.* /setowner=%Domain%\%User%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Change the ownership of a folder &lt;/u&gt;&lt;br /&gt;subinacl /file %Path% /setowner=%Domain%\%User%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Logical Disk Information&lt;br /&gt;&lt;/u&gt;wmic /node:%server% path Win32_LogicalDisk&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Physical Disk Information &lt;/u&gt;&lt;br /&gt;wmic /node:%server% path Win32_DiskPartition&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-1055575373142513601?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=1055575373142513601' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1055575373142513601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/1055575373142513601'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/useful-ntfs-and-security-command-line.html' title='Useful NTFS and security command-line operations'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-3886924876948900341</id><published>2008-09-08T20:30:00.003+10:00</published><updated>2008-09-29T17:09:02.232+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Printing'/><title type='text'>Useful Windows Printer command-line operations</title><content type='html'>The commands below are a subset of the complete command list found in &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;Useful command-lines&lt;/a&gt;, and perform various operations against printers on a Windows 200x server.&lt;br /&gt;&lt;br /&gt;The commands are useful for querying information from one or more printers, as well as making changes to configuration items for printers, including queues, shares, AD information and drivers. Generally Microsoft Windows printing is relatively simple - but add MSCS clustering, the plethora of PCL unidrv versions out there and badly written third-party drivers - troubleshooting can be quite difficult.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use a custom WMIC alias to report printer info from a cluster node in CSV&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" spoolerjobs list /format:table&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use a custom WMIC alias to report sorted HTML printer info from a cluster node&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" spoolerjobs list /format:htable:"datatype=number":"sortby=TotalJobsPrinted"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use a custom WMIC alias to report a brief summary of printer statistics&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" spoolerjobs list brief /format:htable:"datatype=number":"sortby=TotalJobsPrinted"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use a custom WMIC alias and xsl to sort print jobs output descending HTML table&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" spoolerjobs list brief /format:"htabledesc-sortby.xsl":"datatype=number":"orderby=descending":"sortby=TotalJobsPrinted" &amp;gt; test.html &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Reset inheritance starting at a folder and recursing&lt;/u&gt;&lt;br /&gt;icacls \\UNC\Path /reset /t /c&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Open a saved printer query window&lt;/u&gt;&lt;br /&gt;rundll32 dsquery,OpenSavedDsQuery %Config%.qds&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query HP printers for the page count using SNMP&lt;/u&gt;&lt;br /&gt;for /f %i in (Printers.txt) do @echo %i &amp; @snmputil walk %i public printmib.prtMarker.prtMarkerTable.prtMarkerEntry.prtMarkerLifeCount &amp;#124; find /i "value"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query printers for job counts &gt;= 1&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" path Win32_PerfFormattedData_Spooler_PrintQueue Where "Jobs&gt;=1" Get Name,Jobs,MaxJobsSpooling,JobErrors,OutOfPaperErrors&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query printer information from AD (speed, memory etc)&lt;br /&gt;&lt;/u&gt;dsquery * %serverDN% -limit 0 -filter "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -attr cn printerName driverName printCollate printColor printLanguage printSpooling driverVersion printStaplingSupported printMemory printRate printRateUnit printMediaReady&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Export printer information from AD (speed, memory etc)&lt;br /&gt;&lt;/u&gt;csvde -f Printers.csv -d %serverDN% -r "(&amp;amp;(objectClass=printQueue)(objectCategory=printQueue))" -l cn,printerName,location,driverName,printCollate,printColor,printLanguage,printSpooling,driverVersion,printStaplingSupported,printMemory,printRate,printRateUnit,printMediaReady&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Modify a printer or all printers on a print server to use the winprint processor&lt;br /&gt;&lt;/u&gt;setprinter \\%Server%[\%Printer%] 2 pPrintProcessor="WinPrint"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the unidrv DLL versions from a list of pingable computers in an OU&lt;br /&gt;&lt;/u&gt;for /f %i in ('"dsquery computer %OU_DN% -limit 0 -o rdn"') do @for /f "tokens=3 delims=: " %m in ('"ping -n 1 %i find /i "reply from""') do @for /f "tokens=1-9" %q in ('"filever \\%~i\C$\windows\system32\spool\drivers\w32x86\3\uni*.dll find /i /v "\\%~i""') do @echo %i,%q,%r,%s,%t,%u,%v,%w,%x,%y&lt;br /&gt;&lt;br /&gt;&lt;u&gt;check printers are being published in the directory through setprinter &lt;/u&gt;&lt;br /&gt;setprinter -show \\%server% 7&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run the 32-bit version of regsvr32 on an x64 platform to register the prnadmin DLL&lt;br /&gt;&lt;/u&gt;c:\WINDOWS\SysWOW64\regsvr32 c:\admin\util\prnadmin.dll&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run the 32-bit version of cscript that accesses a 32-bit DLL on x64&lt;br /&gt;&lt;/u&gt;c:\WINDOWS\SysWOW64\cscript portmgr.vbs&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use SetPrinter to capture all settings for a printer &lt;/u&gt;&lt;br /&gt;for %i in (0 1 2 3 4 5 6 7 8 9) do setprinter -show \\%server%\%printer% %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report print queue current length and various performance statistics&lt;br /&gt;&lt;/u&gt;wmic /node:"%server%" path Win32_PerfFormattedData_Spooler_PrintQueue Get Name,Jobs,TotalJobsPrinted,TotalPagesPrinted,MaxJobsSpooling,JobErrors,OutOfPaperErrors&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List printer drivers on a physical or cluster Windows 2003 server &lt;/u&gt;&lt;br /&gt;cscript drvmgr.vbs -l -c \\%server%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Print a test page to one or more printers&lt;br /&gt;&lt;/u&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do cscript prnctrl.vbs -t -b \\%PrintServer%\%i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a list of printers, create an LPR port for each&lt;br /&gt;&lt;/u&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do @cscript portmgr.vbs -a -c \\%PrintServer% -p %i -h %k -t LPR -q %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a list of printers, create a printer using the specified driver/port&lt;br /&gt;&lt;/u&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do @cscript prnmgr.vbs -a -c \\%PrintServer% -b %i -m "%j" -r %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a list of printers, set the location, share name and publish in AD &lt;/u&gt;&lt;br /&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do @cscript prncfg.vbs -s -b \\%PrintServer%\%i -h %i -l "%l" +published&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a list of printers, set glocal default printer properties to duplex&lt;br /&gt;&lt;/u&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do @setprinter \\%PrintServer%\%i 8 "pDevMode=dmDuplex=2,dmCollate=1,dmFields=duplex collate"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a list of printers, set printer permissions to allow for queue management&lt;br /&gt;&lt;/u&gt;for /f "tokens=1-4 delims=," %i in (%Printer.txt%) do @c:\util\subinacl /printer \\%PrintServer%\%i /grant=%Domain%\%Group%=M&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find printer event log entries for the last 15 minutes&lt;br /&gt;&lt;/u&gt;for /f %i in ('cscript //nologo c:\data\scripts\updated\time\finddatetime.vbs') do wmic /node:"%server%" path Win32_NTLogEvent WHERE "SourceName='Print' AND LogFile='System' AND EventCode=10 AND TimeGenerated &gt; '%i'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find printer event log entries for the specified user &lt;/u&gt;&lt;br /&gt;wmic /node:"%server" path Win32_NTLogEvent WHERE "SourceName='Print' AND LogFile='System' AND EventCode=10 AND User='%Domain%\\%Username%'" Get User,TimeGenerated,InsertionStrings&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Automated Printer configuration&lt;br /&gt;&lt;/u&gt;rundll32 printui.dll,PrintUIEntry /?&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a port using prnadmin.dll on a cluster node&lt;br /&gt;&lt;/u&gt;cscript portmgr.vbs -a -c \\%PrintServer% -p %Printer% -h %PrinterIP% -t raw -n 9100&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a printer using prnadmin.dll on a cluster node&lt;br /&gt;&lt;/u&gt;cscript prnmgr.vbs -a -c \\%PrintServer% -b %Printer% -m "HP Universal Printing PCL 6" -r %Printer%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Set printer configuration using prnadmin.dll on a cluster node&lt;br /&gt;&lt;/u&gt;cscript prncfg.vbs -s -b \\%PrintServer%\%Printer% -h %Printer% -l "Building/Level 1" +published&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Dump printer log entries &lt;/u&gt;&lt;br /&gt;dumpel -s \\%PrintServer% -l System -e 10 -m Print -d 1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add an x64 print driver to a cluster node&lt;br /&gt;&lt;/u&gt;rundll32 printui.dll,PrintUIEntry /ia /c \\%PrintServer% /m "HP Color LaserJet 8550 PCL 5c" /h "x64" /v "Windows XP and Windows Server 2003" /f hpc8550t.inf&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add an x86 print driver to a cluster node &lt;/u&gt;&lt;br /&gt;rundll32 printui.dll,PrintUIEntry /ia /c \\%PrintServer% /m "HP Color LaserJet 8550 PCL 5c" /h "x86" /v "Windows 2000, Windows XP and Windows Server 2003" /f hpc8550b.inf&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Add to the permissions on a printer&lt;br /&gt;&lt;/u&gt;subinacl /printer \\%PrintServer%\%Printer% /grant=%Domain%\%Group%=M&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List the printers on a server &lt;/u&gt;&lt;br /&gt;cscript "c:\Program Files\Windows Resource Kits\Tools\prnmgr.vbs" -l -c \\%PrintServer% find /i "printername"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Set the glocal default printer properties to allow duplexing&lt;br /&gt;&lt;/u&gt;setprinter \\%PrintServer%\%i 8 "pDevMode=dmDuplex=2,dmCollate=1,dmFields=duplex collate"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the printers published against a specific computer account&lt;br /&gt;&lt;/u&gt;dsquery * %ComputerDN%" -attr printShareName&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query all printers published in the Active Directory &lt;/u&gt;&lt;br /&gt;dsquery * domainroot -filter "(objectCategory=printQueue)" -limit 0&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show the current default settings send down to clients from a printer&lt;br /&gt;&lt;/u&gt;setprinter -show \\%printServer%\%Printer% 8&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the print processor used by all printers on a print server &lt;/u&gt;&lt;br /&gt;setprinter -show \\%server% 2 findstr /c:"pPrinterName" /c:"pPrintProcessor"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check through SNMP whether a printer supports a duplexing media path&lt;br /&gt;&lt;/u&gt;snmputil walk %printer% public printmib.prtMediaPath.prtMediaPathTable.prtMediaPathEntry.prtMediaPathDescription&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check through SNMP the printer device model &lt;/u&gt;&lt;br /&gt;snmputil getnext %printer% public host.hrDevice.hrDeviceTable.hrDeviceEntry.hrDeviceDescr&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View/Modify the ACL security on spooler pipe&lt;br /&gt;&lt;/u&gt;pipesec \\%computer%\pipe\spoolss&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query printer tray configuration of printers on a cluster (HP UPD)&lt;br /&gt;&lt;/u&gt;for /f %i in (Printers.txt) do @for /f "tokens=1,2,*" %m in ('"reg query \\%PrintServer%\HKEY_LOCAL_MACHINE\Cluster\Resources\%ClusterResourceGUID%\Parameters\Printers\%i\PrinterDriverData /v InputSlot 2&gt;nul find /i "InputSlot" &amp;amp; if errorlevel 1 echo 1 2 NotFound"') do @echo %i,%o&gt;&gt;PrinterTrays.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use SNMP to get the printer media path, indicating simplex/duplex capabilities&lt;br /&gt;&lt;/u&gt;for /f %i in (Printers.txt) do @for /f "tokens=3,*" %m in ('"snmputil walk %i public printmib.prtMediaPath.prtMediaPathTable.prtMediaPathEntry.prtMediaPathDescription 2&gt;nul find /i "value" &amp;amp; if errorlevel 1 echo 1 2 3 NotFound"') do @echo %i,%n&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-3886924876948900341?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=3886924876948900341' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3886924876948900341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/3886924876948900341'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/useful-windows-printer-command-line.html' title='Useful Windows Printer command-line operations'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-4239270023476859842</id><published>2008-09-08T20:27:00.003+10:00</published><updated>2008-09-29T17:09:12.323+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='Cluster'/><title type='text'>Useful Windows MSCS Cluster command-line operations</title><content type='html'>The commands below are a subset of the complete command list found in &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;Useful command-lines&lt;/a&gt;, and are command-line operations for Microsoft Windows MSCS server clusters. Most commands are based around the Microsoft cluster.exe utility, with some using WMI, defrag and diruse to provide information on cluster disk resources.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find cluster disk size and free space in CSV format&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%","%server%","%server%","%server%" path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET SystemName,Name,Size,FreeSpace,VolumeName /format:csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find cluster disk size and free space in modified CSV format with thousand sep.&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%","%server%","%server%","%server%" path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET Name,Size,FreeSpace,VolumeName  /format:csv2&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report the windows MSCS cluster virtual groups&lt;/u&gt;&lt;br /&gt;cluster /cluster:%cluster% group /prop &amp;#124; find /i "description" &amp;#124; find /i /v "pbx" &amp;#124; find /i /v "cluster"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report folders being archived from Enterprise Vault EV FSA&lt;/u&gt;&lt;br /&gt;sqlcmd -S sqlServer%\%instance% -o ArchivedFolders.txt -d %enterprisevaultdirectory% -W -s "," -Q "select FSVP.UncName, FSVP.VolumeName, FSFE.FolderPath, FSVP.UncName + '\' + FSVP.VolumeName + '\' + FSFE.FolderPath as 'Path' from dbo.FileServerFolderEntry FSFE inner join dbo.vw_FileServer_Volume_Policy FSVP on FSFE.VolumeEntryID = FSVP.VolumeEntryID"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report folders from the one or more servers not being archived compared to FSA export&lt;/u&gt;&lt;br /&gt;for %i in (\\%server%\share% \\%server%\share% ) do @for /f "tokens=1-4,*" %m in ('"dir %i\* /ad /tc &amp;#124; find "DIR" &amp;#124; find "-""') do @find /i "%q" ArchivedFolders.txt &amp;gt;nul &amp; @If errorlevel 1 (echo %q,%i,%m %n %o) &amp;gt;&amp;gt; NotArchived.csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Delete a cluster resource type &lt;/u&gt;&lt;br /&gt;cluster restype "%resource_name%" /delete /type&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find cluster disk size and free space&lt;br /&gt;&lt;/u&gt;echo clusnode1 &gt; clusternodes.txt &amp;amp; echo clusnode2 &gt;&gt; clusternodes.txt &amp;amp; echo clusnode3 &gt;&gt; clusternodes.txt &amp;amp; echo clusnode4 &gt;&gt; clusternodes.txt &amp;amp; wmic /node:@clusternodes.txt path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET SystemName,Name,Size,FreeSpace,VolumeName&lt;br /&gt;&lt;br /&gt;&lt;u&gt;show the MSCS cluster multicast address properties&lt;br /&gt;&lt;/u&gt;cluster /cluster:%Cluster% network "%PublicNetwork%" /priv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the MSCS cluster resources&lt;br /&gt;&lt;/u&gt;cluster /cluster:%Cluster% res /prop find /i "sr"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the disks currently owned by each cluster node&lt;br /&gt;&lt;/u&gt;for %i in (%server1% %server2%) do @wmic /node:"%i" path Win32_LogicalDisk WHERE "FileSystem='NTFS' AND Name != 'C:' AND Name != 'D:'" GET SystemName,Name find /i "%server_prefix%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;In a 2003 cluster, find each disk volume and analyse file fragmentation&lt;br /&gt;&lt;/u&gt;for /f "tokens=2,5,6,8" %i in ('"cluster /cluster:%cluster% resource /prop find /i "disk" find /i "description" find /i "%CommonTag%""') do echo \\%i\%k %j %l&gt;&gt; Defrag_%i_%j.txt &amp;amp;&amp;amp; psexec \\%i defrag %k -a -v &gt;&gt; Defrag_%i_%j.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;From cluster defrag analysis, print out details for each cluster volume &lt;/u&gt;&lt;br /&gt;for /f "tokens=1,* delims=:" %i in ('"findstr /i /c:%server% /c:"Total files" /c:"Volume size" /c:"Used space" /c:"Percent free space" /c:"Total fragmented files" defrag*"') do @echo %j&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a cluster file share: &lt;/u&gt;&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /create /group:"%group%" /type:"File Share"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /priv path="%path%"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /priv Sharename=%share_name%&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /priv Remark="File Share Remark"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /prop Description="File Share Description"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /priv security=Everyone,grant,F:security&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /AddDep:"%networkname_res%"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /AddDep:"%disk_res%"&lt;br /&gt;cluster /cluster:%cluster% res "%share_res_name%" /On&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create an ABE resource for the file share&lt;br /&gt;&lt;/u&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /create /group:"%group%" /type:"Generic Application"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /priv CommandLine="cmd.exe /k abecmd.exe /enable %share_name%"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /priv CurrentDirectory="%SystemRoot%"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /priv InteractWithDesktop=0&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /priv UseNetworkName=0&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /prop SeparateMonitor=1&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /prop Description="Access Based Enumeration for %share_name% File Share"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /AddDep:"%networkname_res%"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /AddDep:"%disk_res%"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /AddDep:"%share_res_name%"&lt;br /&gt;cluster /cluster:%cluster% res "%shareabe_res_name%" /On&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-4239270023476859842?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=4239270023476859842' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4239270023476859842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/4239270023476859842'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/useful-windows-mscs-cluster-command.html' title='Useful Windows MSCS Cluster command-line operations'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-8040465696151703472</id><published>2008-09-08T20:26:00.003+10:00</published><updated>2008-09-29T17:09:25.054+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='VMware'/><title type='text'>Useful VMware ESX and VC command-line operations</title><content type='html'>The commands below are a subset of the complete command list found in &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;Useful command-lines&lt;/a&gt;, and are a combination of ESX service console commands, PowerShell VI Toolkit or SQL commands (reading from a VirtualCenter database). Note that these have been tested on VI3 - ESX 3.0.x, VC 2.0.x, and some have also been used on VI3.5 - ESX 3.5 / VC 2.5.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;ESX service console&lt;br /&gt;&lt;/strong&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report the hosts controlled by a VirtualCentre instance&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select [Name] from vpxv_hosts order by [Name]"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Report the hosts controlled by a VirtualCentre instance&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select DNS_Name, IP_Address, PRODUCT_FULLNAME from vpx_host Order by DNS_Name"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine LUN mapping and size&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select VMS.Name, TDS.Name, Cast(Round(Sum(Cast(VDISK.CAPACITY as numeric))/1024/1024/1024, 1) as int) as 'Total Disk', Cast(Round(Sum(Cast(VDISK.FREE_SPACE as numeric))/1024/1024/1024, 1) as int) as 'Free Disk' from vpxv_vms VMS inner join vpxv_vm_datastore VVMDS on VMS.VMID = VVMDS.VM_ID inner join vpx_datastore TDS on VVMDS.DS_ID = TDS.ID inner join VPX_GUEST_DISK VDISK on VMS.VMID = VDISK.VM_ID group by VMS.Name, TDS.Name Order by TDS.Name, VMS.Name"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Allow Dell OpenManage Server Administrator traffic through ESX &lt;/u&gt;&lt;br /&gt;esxcfg-firewall -o 1311,tcp,in,OpenManageRequest&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Dump the VMware IP config&lt;br /&gt;&lt;/u&gt;cat /proc/vmware/net/tcpip/ifconfig&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View network traffic in the vswif service console interface&lt;br /&gt;&lt;/u&gt;/usr/sbin/tcpdump -i vswif0 grep -v ssh&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check the Legato AAM HA agent &lt;/u&gt;&lt;br /&gt;cat /opt/LGTOaam512/log/aam_config_util_addnode.log&lt;br /&gt;&lt;br /&gt;&lt;u&gt;VMware HA Legato AAM, list the cluster manager&lt;br /&gt;&lt;/u&gt;/opt/LGTOaam512/bin/ftcli -domain vmware -timeout 60 -cmd "listrules"&lt;br /&gt;(run 'FT_DIR=/opt/LGTOaam512' and then 'export FT_DIR' first)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;VMware HA Legato AAM, list the cluster nodes &lt;/u&gt;&lt;br /&gt;/opt/LGTOaam512/bin/ftcli -domain vmware -connect %node% -port 8042 -timeout 60 -cmd "listnodes"&lt;br /&gt;(run 'FT_DIR=/opt/LGTOaam512' and then 'export FT_DIR' first)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query ESX for SNMPD service firewall configuration&lt;br /&gt;&lt;/u&gt;esxcfg-firewall -q snmpd&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query vmfs volumes for snapshot files from the console&lt;br /&gt;&lt;/u&gt;ls -Ral /vmfs/volumes/*.* grep .vmsn&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Change security on a file in the ESX service console &lt;/u&gt;&lt;br /&gt;chmod u+rwx,g+rx,o+rx somefile&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Register a Virtual Machine in ESX&lt;br /&gt;&lt;/u&gt;vmware-cmd -s register "/path/to/vmx/or/vmtx"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;unregister a Virtual Machine in ESX&lt;/u&gt;&lt;br /&gt;vmware-cmd -s unregister "/path/to/vmx/or/vmtx"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Enable SSH client out on an ESX host firewall, permitting SCP as well&lt;br /&gt;&lt;/u&gt;esxcfg-firewall -e sshClient&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the ESX firewall to determine whether SSH client is allowed out &lt;/u&gt;&lt;br /&gt;esxcfg-firewall -q grep sshClient&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Query the VirtualCenter Database&lt;br /&gt;&lt;/strong&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Query VMs and their MAC addresses from the VC database&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -q "select ENT.Name, NET.MAC_Address from VPX_GUEST_NET_ADAPTER NET inner join VPX_ENTITY ENT on NET.VM_ID = ENT.ID"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine Disk Totals&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select VM.Name, Cast(Round(Sum(Cast(VDISK.CAPACITY as numeric))/1024/1024/1024, 1) as int) as 'Total Disk', Cast(Round(Sum(Cast(VDISK.FREE_SPACE as numeric))/1024/1024/1024, 1) as int) as 'Free Disk' from dbo.VPX_GUEST_DISK VDISK inner join VPXV_VMS VM on VDISK.VM_ID = VM.VMID group by VM.Name compute sum(Cast(Round(Sum(Cast(VDISK.CAPACITY as numeric))/1024/1024/1024, 1) as int))"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine Disk information &lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select VM.Name, VDISK.* from dbo.VPX_GUEST_DISK VDISK inner join VPXV_VMS VM on VDISK.VM_ID = VM.VMID"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine Disk Total&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select Cast(Round(Sum(Cast(VDISK.CAPACITY as numeric))/1024/1024/1024, 1) as int) from dbo.VPX_GUEST_DISK VDISK"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query VirtualCentre for hot migration events &lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select Create_Time as 'Relocation Start', UserName, VM_Name, Host_Name as 'Host Source', (select Host_Name from dbo.VPX_EVENT Where Chain_ID = EVTDEST.Chain_ID and event_type = 'vim.event.VmMigratedEvent') as 'Host Destination', ComputeResource_Name, DataCenter_Name from dbo.VPX_EVENT EVTDEST where event_type = 'vim.event.VmBeingHotMigratedEvent'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query VirtualCentre for migration events&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select Create_Time as 'Relocation Start', UserName, VM_Name, Host_Name as 'Host Source', (select Host_Name from dbo.VPX_EVENT Where Chain_ID = EVTDEST.Chain_ID and event_type = 'vim.event.VmRelocatedEvent') as 'Host Destination', ComputeResource_Name, DataCenter_Name from dbo.VPX_EVENT EVTDEST where event_type = 'vim.event.VmBeingRelocatedEvent'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query VirtualCentre for DRS migration events&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select Create_Time as 'Relocation Finished', VM_Name, Host_Name as 'Host Destination', (select Host_Name from dbo.VPX_EVENT Where Chain_ID = EVTDEST.Chain_ID and event_type = 'vim.event.VMBeingHotMigratedEvent') as 'Host Source', ComputeResource_Name, DataCenter_Name from dbo.VPX_EVENT EVTDEST where event_type = 'vim.event.DrsVmMigratedEvent'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine details&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select ENT.Name as 'Name', DNS_Name as 'DNS Name', Guest_OS as 'OS', Mem_Size_MB as 'Mem', Num_VCPU as 'CPU', Num_NIC as 'NIC', IP_Address as 'IP', NET.MAC_Address as 'MAC Address', VM.FILE_Name as 'VMX location' from vpx_vm VM inner join VPX_GUEST_NET_ADAPTER NET on VM.ID = NET.VM_ID inner join VPX_ENTITY ENT on VM.ID = ENT.ID where dns_name like '%'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine snapshots (GMT+10)&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select ENT.Name as 'Name', DNS_Name as 'DNS Name', Guest_OS as 'OS', Mem_Size_MB as 'Mem', IP_Address as 'IP', VM.FILE_Name as 'VMX location', VM.Suspend_Time as 'Suspend Time', VM.Suspend_Interval as 'Suspend Interval', VMS.Snapshot_Name as 'Snapshot Name', VMS.Snapshot_Desc 'Snapshot Description', DateAdd(Hour, 10, VMS.Create_Time) as 'Snapshot Time', VMS.Is_Current_Snapshot 'Current Snapshot' from vpx_vm VM inner join VPX_GUEST_NET_ADAPTER NET on VM.ID = NET.VM_ID inner join VPX_ENTITY ENT on VM.ID = ENT.ID inner join VPX_SNAPSHOT VMS on VM.ID = VMS.VM_ID&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine LUN attachments &lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select VMS.Name, TDS.Name from vpxv_vms VMS inner join vpxv_vm_datastore VVMDS on VMS.VMID = VVMDS.VM_ID inner join vpx_datastore TDS on VVMDS.DS_ID = TDS.ID Order by VMS.Name"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for Virtual Machine config LUN&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select VMS.Name as 'VM Name', TDS.Name as 'Config Datastore', SubString(ConfigFileName, CharIndex('/', ConfigFileName, Len('sanfs://vmfs'))+1, 255) as 'Config Path' from vpxv_vms VMS inner join vpx_datastore TDS on TDS.Storage_URL = SubString(VMS.ConfigFileName, 1, CharIndex('/', VMS.ConfigFileName, Len('sanfs://vmfs'))) Order By 'Config Datastore'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for volume total and free disk space&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select Name, Cast(Round(Cast(Capacity as numeric)/1024/1024/1024, -1) as int) as 'Total Space', Cast(Round(Cast(Free_Space as numeric)/1024/1024/1024, -1) as int) as 'Free Space', Type from vpx_Datastore"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find VM distribution on VMware cluster physical nodes &lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "Select VH.DNS_NAME as 'Host', count(VM.HOST_ID) from vpx_vm VM inner join vpx_host VH on VM.HOST_ID = VH.ID group by VM.HOST_ID, VH.DNS_NAME order by 'Host'"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query the Virtual Centre/VC database for VM CPU alarms&lt;br /&gt;&lt;/u&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select ALR.Created_Time, ENT.Name from vpx_alarm_runtime ALR inner join vpx_alarm AL on ALR.Alarm_ID = AL.Alarm_ID inner join vpx_entity ENT on ALR.Entity_ID = ENT.ID where AL.Name = 'Virtual Machine CPU Usage' order by created_time"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;PowerShell VI Toolkit &lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Use the VI Toolkit Powershell snap-in to query for snapshots&lt;br /&gt;&lt;/u&gt;Get-VM Get-Snapshot export-csv -path c:\temp\VMsnapshots.csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use the VI Toolkit Powershell snap-in to query for snapshot information&lt;br /&gt;&lt;/u&gt;Get-VM Get-Snapshot foreach-object {$out= $_.VM.Name + "," + $_.Name + "," + $_.Description + "," + $_.PowerState; $out}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;ESX Server Advanced Configuration Options &lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Hide LUNs with advanced ESX options&lt;br /&gt;&lt;/u&gt;disk.MaskLUNs: vmhba0:0:4-5;vmhba1:0:4-5&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;Other &lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;SNMP check against ESX&lt;br /&gt;&lt;/u&gt;Snmputil.exe get %host% %community% .iso.org.dod.internet.private.enterprises.6876.1.1.0&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br&gt;&lt;br /&gt;Wayne's World of IT (WWoIT), Copyright 2008 Wayne Martin.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6043156720447404006-8040465696151703472?l=waynes-world-it.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6043156720447404006&amp;postID=8040465696151703472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8040465696151703472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6043156720447404006/posts/default/8040465696151703472'/><link rel='alternate' type='text/html' href='http://waynes-world-it.blogspot.com/2008/09/useful-vmware-esx-and-vc-command-line.html' title='Useful VMware ESX and VC command-line operations'/><author><name>Wayne Martin</name><uri>http://www.blogger.com/profile/09719833406577070443</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6043156720447404006.post-2214993242355042653</id><published>2008-09-08T20:24:00.002+10:00</published><updated>2008-09-29T17:10:29.745+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Command-line'/><title type='text'>Useful general command-line operations</title><content type='html'>The commands below are a subset of the complete command list found in &lt;a href="http://waynes-world-it.blogspot.com/2008/09/useful-command-lines.html"&gt;Useful command-lines&lt;/a&gt;, and are the remainder of command-line operations that didn't fit into one of the other categories I've used.&lt;br /&gt;&lt;br /&gt;Each command-line can be copied and pasted at the command prompt, if you use a batch file you'll need to reference variables with double-percent (%%).&lt;br /&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Open the administrative tools start menu list&lt;/u&gt;&lt;br /&gt;control admintools&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Open the scheduled tasks special folder&lt;/u&gt;&lt;br /&gt;control SCHEDTASKS&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disable hibernation&lt;/u&gt;&lt;br /&gt;powercfg -h off&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show network interface statistics (packets/errors/bytes)&lt;/u&gt;&lt;br /&gt;netstat -e&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote processes and the command-line parameters with PowerShell&lt;/u&gt;&lt;br /&gt;Get-WmiObject win32_process &amp;#124; Format-Table ExecutablePath,Caption,CommandLine,CreationDate,WorkingSetSize,ProcessId&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create an IIS virtual directory&lt;/u&gt;&lt;br /&gt;cscript C:\WINDOWS\system32\iisvdir.vbs /create "Default Web Site" %Alias% %rootPath%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC to get instances of a class and format the output as CSV&lt;/u&gt;&lt;br /&gt;wmic path win32_process get name,commandline /format:csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the current CPU utilisation for processes using WMI&lt;/u&gt;&lt;br /&gt;wmic /node:"%computer%" path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use JT to update a scheduled task's working directory&lt;/u&gt;&lt;br /&gt;jt.exe /sac \\%computer%\c$\windows\Tasks\%Task%.job /sj WorkingDirectory = "%workingdir%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC aliases to format the output in CSV or XML&lt;/u&gt;&lt;br /&gt;wmic process list /format:xml &amp;#124; wmic process list /format:csv&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC aliases to format the output in HTML TABLE, MOFCSV or XML&lt;/u&gt;&lt;br /&gt;wmic process list /format:htable &amp;#124; wmic process list /format:HMOF&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC aliases to sort the output in HTML&lt;/u&gt;&lt;br /&gt;wmic process list /format:htable:"sortby=Name" &amp;gt; test.html&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC aliases to filter and sort the output in CSV&lt;/u&gt;&lt;br /&gt;wmic process get name /format:csv:"datatype=text":"sortby=Name" &lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC remotely aliases to retrieve command-line process arugments&lt;/u&gt;&lt;br /&gt;wmic /node:"%server%" process get name,CommandLine /format:csv:"sortby=Name"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use WMIC wmic aliases to sort the result set by number&lt;/u&gt;&lt;br /&gt;wmic Logon get /Format:htable:"datatype=number":"sortby=LogonType"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check NULL sessions to see if user/group information can be enumerated&lt;/u&gt;&lt;br /&gt;hunt.exe OR winfo.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disable strict name checking for a machine&lt;/u&gt;&lt;br /&gt;reg add \\%computer%\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters /v DisableStrictNameChecking /t reg_dword /d 0x1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;List transports and if they are bound to NetBIOS (NetBT over TCP/IP)&lt;/u&gt;&lt;br /&gt;browstat dumpnet&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View the browse list using NetServerEnum to a domain or server&lt;/u&gt;&lt;br /&gt;browstat view \Device\NetBT_Tcpip_{972F2574-31D4-4467-8BC0-70B3C57C1279} %domain%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote cscript processes and the scripts they are running (arguments)&lt;/u&gt;&lt;br /&gt;wmic /node:"%computer%" path win32_process Where "Caption Like '%cscript%' " get Caption,CommandLine,CreationDate,WorkingSetSize,ProcessId&lt;br /&gt;&lt;/span&gt;&lt;span class="fullpost"&gt;&lt;span style="font-family:courier new;font-size:78%;"&gt;&lt;br /&gt;&lt;u&gt;Connect to a named SQL instance through Management Studio&lt;/u&gt;&lt;br /&gt;%server%\%instance_name%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query an Enterprise Vault Directory database for file group information(view)&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select * from dbo.view_FileGroupAndFileGroupFile"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query an Enterprise Vault Directory database for file group information(table)&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database% -W -s "," -Q "select FileGroupName, FileGroupDescription, FileSpecification from filegroupfile inner join Filegroup on FileGroupFile.FileGroupEntryID = FileGroup.FileGroupEntryID Order By FileGroupName"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query an Enterprise Vault Directory database for index errors&lt;/u&gt;&lt;br /&gt;sqlcmd -S %sqlServer% -d %Database%  -W -s "," -Q "Select ArchiveName, ArchiveStatus, IndexRootPath, Offline, Failed, Rebuilding, IndexedItems, FailedItems from IndexVolumeView where (rebuilding != 0) OR (Failed != 0) OR (Offline != 0)"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Extract events from a non-standard event log&lt;/u&gt;&lt;br /&gt;wmic /node:"%computer%" path Win32_NTLogEvent WHERE "SourceName='%EventSource%' AND LogFile='%LogName%' AND EventCode=%eventcode%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Start a process in low priority&lt;/u&gt;&lt;br /&gt;cmd /c start "LowPriority" /BELOWNORMAL notepad "a file.txt"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Software Information for each server&lt;/u&gt;&lt;br /&gt;for /f %i in (Output from 'Domain Controllers') do psinfo \\%i &amp;gt; ServerInfo_%i.txt &amp;amp; filever \\%i\admin$\explorer.exe \\%i\admin$\system32\vbscript.dll \\%i\admin$\system32\kernel32.dll \\%i\admin$\system32\wbem\winmgmt.exe \\%i\admin$\system32\oleaut32.dll &amp;gt;&amp;gt; ServerInfo_%i.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check Terminal Services Delete Temp on Exit flag&lt;/u&gt;&lt;br /&gt;For /f %i in (Output from 'Domain Controllers') do Reg query “\\%i\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server” /v DeleteTempDirsOnExit&lt;br /&gt;&lt;br /&gt;&lt;u&gt;For each XP workstation, query the current site and what Group Policy info&lt;/u&gt;&lt;br /&gt;@dsquery * domainroot -filter "(&amp;amp;(objectCategory=Computer)(operatingSystem=Windows XP Professional))" -limit 0 -attr cn &amp;gt; Workstations.txt &amp;amp; @For /f %i in (Workstations.txt) do @ping %i -n 1 &amp;gt;NUL &amp;amp; @if ErrorLevel 0 If NOT ErrorLevel 1 @Echo %i &amp;amp; for /f "tokens=3" %k in ('"reg query "\\%i\hklm\software\microsoft\windows\currentversion\group policy\history" /v DCName Find /i "DCName""') do @for /f %m in ('"nltest /server:%i /dsgetsite find /i /v "completed successfully""') do @echo %i,%k,%m&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Time offsets from client diagnostics&lt;/u&gt;&lt;br /&gt;@for %i in (*time*.txt) do @for /f "tokens=2 delims=:" %j in ('"find /i "NTP:" %i find /i "NTP:""') do @echo %i,%j&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote NIC bandwidth&lt;/u&gt;&lt;br /&gt;wmic /node:%server% path Win32_PerfRawData_Tcpip_NetworkInterface GET Name,CurrentBandwidth&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote free physical memory&lt;/u&gt;&lt;br /&gt;wmic /node:%Computer% path Win32_OperatingSystem GET FreePhysicalMemory&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote system information&lt;/u&gt;&lt;br /&gt;SystemInfo /s %Computer%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disk statistics, including the number of files on the filesystem&lt;/u&gt;&lt;br /&gt;chkdsk /i /c&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query IIS web sites&lt;/u&gt;&lt;br /&gt;iisweb /s %Server% /query "Default Web Site"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Check port state and connectivity&lt;/u&gt;&lt;br /&gt;portqry -n %server% -e %endpoint% -v&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the parent of a process&lt;/u&gt;&lt;br /&gt;wmic path Win32_Process WHERE Name='%ProcessName%' GET Name,ParentProcessId&lt;br /&gt;&lt;br /&gt;&lt;u&gt;PSCP secure copy a file&lt;/u&gt;&lt;br /&gt;pscp %file% %user%@%target%:/target/path&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Accept a input and store in a variable&lt;/u&gt;&lt;br /&gt;set /p &amp;lt;variable&amp;gt;=&amp;lt;prompt&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remote Computer Management MMC&lt;/u&gt;&lt;br /&gt;compmgmt.msc /computer=%1&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create a placeholder file&lt;/u&gt;&lt;br /&gt;fsutil file createnew &amp;lt;filename&amp;gt;&amp;lt;size&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Device Manager showing hidden devices&lt;/u&gt;&lt;br /&gt;SET DEVMGR_SHOW_NONPRESENT_DEVICES=1 &amp;amp; Devmgmt.msc&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Echo both stdout and stderr to the same file&lt;/u&gt;&lt;br /&gt;&amp;gt; output.txt 2&amp;lt;&amp;amp;1 &lt;br /&gt;&lt;br /&gt;&lt;u&gt;For the first token in each line in A, compare the second token in B&lt;/u&gt;&lt;br /&gt;for /f "tokens=1-3 delims=," %i in ('"find /i /v "&amp;lt;exclude&amp;gt;" a.txt"') do @for /f "tokens=1-3 skip=2 delims=," %m in ('"find /i "%i" b.txt"') do @if /i "%i"=="%m" @if /i "%j" NEQ "%n" @echo %i,%j,%n&lt;br /&gt;&lt;br /&gt;&lt;u&gt;For the first token in each line in A, find not in B&lt;/u&gt;&lt;br /&gt;for /f "skip=2 delims=," %i in ('" find /i /v "&amp;lt;exclue&amp;gt;" a.txt"') do @find /i "%i" b.txt 1&amp;gt;nul 2&amp;gt;nul &amp;amp; @if errorlevel 1 echo %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the DFS roots from Active Directory&lt;/u&gt;&lt;br /&gt;dsquery * "CN=DFS Volumes,CN=File Replication Service,CN=System,DC=domainRoot"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the DFS roots using dfsutil&lt;/u&gt;&lt;br /&gt;dfsutil /domain:%domain% /view&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View info on a DFS root&lt;/u&gt;&lt;br /&gt;dfsutil /root:&amp;lt;dfsroot&amp;gt; /view&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Port Query testing network connectivity to the specified endpoint&lt;/u&gt;&lt;br /&gt;portqry -n %target% -e 135&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Test RPC endpoints&lt;/u&gt;&lt;br /&gt;rpcdump /s %computer% /v /i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Extract a cabinet from an MSI stream&lt;/u&gt;&lt;br /&gt;msidb -d "%msi%" -x "%cabinet name%" (get the cabinet name from the Media table using orca, and the filenames from the File table)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;Add a system environment variable&lt;/u&gt;&lt;br /&gt;setenv -a test %path%;%AdminRoot%\Utils&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Lock the workstation from the commandline&lt;/u&gt;&lt;br /&gt;%windir%\System32\rundll32.exe user32.dll, LockWorkStation&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Perform idle time optimisation (eg. file placement optimisation)&lt;/u&gt;&lt;br /&gt;rundll32.exe advapi32.dll,ProcessIdleTasks&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Hardware Installation from an INF file&lt;/u&gt;&lt;br /&gt;%SystemRoot%\System32\rundll32.exe setupapi,InstallHinfSection DefaultInstall&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Refresh network configuration after policy changes (eg SearchList)&lt;/u&gt;&lt;br /&gt;RunDLL32.EXE netshell.dll,NetSetupFinishInstall&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query SMS inventory information from the commandline&lt;/u&gt;&lt;br /&gt;wmic /namespace:\\root\sms\site_%SiteCode% /node:%Computer% path SMS_G_System_SYSTEM_ENCLOSURE WHERE ResourceID='%RID%'&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote connections to a server&lt;/u&gt;&lt;br /&gt;wmic /node:%server% path win32_serverconnection&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find remote sessions to a server&lt;/u&gt;&lt;br /&gt;wmic /node:%server% path win32_serversession&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find security patches applicable on a machine with MBSA&lt;/u&gt;&lt;br /&gt;wmic /node:%computer% path Win32_PatchState&lt;br /&gt;&lt;br /&gt;&lt;u&gt;For services that aren't running, find their start type&lt;/u&gt;&lt;br /&gt;for /f "skip=4 tokens=1-3" %i in ('sclist \\%computer%') do @if "%i" NEQ "running" @for /f "tokens=4" %m in ('"sc \\%computer% qc %j find /i "START_TYPE""') do @echo %i,%j,%k,%m&lt;br /&gt;&lt;br /&gt;&lt;u&gt;For computers listed, if a service exists, start it&lt;/u&gt;&lt;br /&gt;for /f %i in (computers.txt) do sclist \\%i find /i "%service_name%" &amp;amp;&amp;amp; sc \\%i start "%service_name%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query a registry value of multiple computers&lt;/u&gt;&lt;br /&gt;for %i in (PC1 PC2 PC3) do @Echo %i &amp;amp; reg query \\%i\hklm\software\%key% /v %Value% find /i "%Value%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;Query the creation date of multiple computer objects&lt;/u&gt;&lt;br /&gt;dsquery * -filter "(&amp;amp;(objectClass=Computer)(objectCategory=Computer)((cn=PC1)(cn=PC2)(cn=PC3)))" -attr CN whenCreated&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query SMS for the creation date of computer records&lt;/u&gt;&lt;br /&gt;select Name0, Creation_Date0 from v_r_system where name0 in('PC1','PC2','PC3')&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find RIS servers hosting the specified image&lt;/u&gt;&lt;br /&gt;for /f "tokens=2 skip=1 delims==, " %i in (RIS_Servers.txt) do @if exist \\%i\reminst\setup\english\%Source% @echo %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Modify Outlook to allow access to blocked attachements&lt;/u&gt;&lt;br /&gt;reg add HKU\S-1-5-21-2091930395-2002392527-14044502-274471\Software\Microsoft\Office\11.0\Outlook\Security /v Level1Remove /t reg_sz /d ".exe"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Open the Find Files Dialog Box&lt;/u&gt;&lt;br /&gt;echo Set objShell = CreateObject("Shell.Application") &amp;gt; test.vbs &amp;amp;&amp;amp; Echo objShell.FindFiles &amp;gt;&amp;gt; test.vbs &amp;amp;&amp;amp; cscript test.vbs&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View Software Installation controlled through AD, both current and history&lt;/u&gt;&lt;br /&gt;gpsiviewer.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;View Group Policy application times&lt;/u&gt;&lt;br /&gt;gptime&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remote GP Update&lt;/u&gt;&lt;br /&gt;rgprefresh&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the tail of lines between two strings to display&lt;/u&gt;&lt;br /&gt;for /f "delims=[]" %i in ('"find /i /N "Forwarders:" A.txt"') do for /f "delims=[]" %m in ('"find /i /N "Command completed successfully." A.txt"') do for /f %p in ('set /a %m-%i') do echo %p&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Turn on RIS debugging&lt;/u&gt;&lt;br /&gt;reg add \\%server%\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Binlsvc\Parameters /v Debug /t reg_dword /d 0x80FFFFFF &amp;amp; sc \\%server% stop binlsvc &amp;amp; sc \\%server% start binlsvc&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Trigger a command to run on a specific event&lt;/u&gt;&lt;br /&gt;eventtriggers /create /TR Test /L Security /EID 680 /T SUCCESSAUDIT /TK calc.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Create an XML file with the MD5 hashes of a set of files&lt;/u&gt;&lt;br /&gt;FCIV&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the shell extensions currently loaded&lt;/u&gt;&lt;br /&gt;ShexView&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find server information&lt;/u&gt;&lt;br /&gt;srvinfo.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;LDAP Query from eDirectory&lt;/u&gt;&lt;br /&gt;ldifde -d %rootDN% -s %NetwareServer% -f output.ldf -a "%UserDN%" *&lt;br /&gt;&lt;br /&gt;&lt;u&gt;csvde export form eDirectory&lt;/u&gt;&lt;br /&gt;csvde -f OutputFile.csv -a "%UserDN%" * -r "(Objectclass=user)" -d "%rootDN%" -s NetwareServer%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Verify installed drivers&lt;/u&gt;&lt;br /&gt;verifier.exe&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Windows Updates Automatic Updates Detect now&lt;/u&gt;&lt;br /&gt;wuauclt /detectnow&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Test for ping and then query computers for network information&lt;/u&gt;&lt;br /&gt;for /f %i in (pcs.txt) do @for /f "tokens=3 delims=: " %m in ('"ping -n 1 %i find /i "reply from""') @do for /f "tokens=*" %p in ('"@wmic /node:%i path Win32_PerfRawData_Tcpip_NetworkInterface GET find /i "1000" find /i /v "MS TCP Loopback interface""') do @echo %i,%m,%p&lt;br /&gt;&lt;br /&gt;&lt;u&gt;WireShark/ethereal filter to exclude 3389 RDP&lt;/u&gt;&lt;br /&gt;!((tcp.srcport == 3389) (tcp.dstport == 3389))&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show NetBIOS SMB lanmanserver binding&lt;/u&gt;&lt;br /&gt;net config server&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Show NetBIOS SMB lanmanworkstation binding&lt;/u&gt;&lt;br /&gt;net config redirector&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the session connection for a username and find the client workstation&lt;/u&gt;&lt;br /&gt;for /f "tokens=2 delims=\" %i in ('"dsquery user -name %user% dsget user -hmdir find /i "%user%""') do @for /f "skip=1 tokens=1-3" %m in ('"wmic /node:"%i" path win32_serversession WHERE "UserName Like '%user%'" Get ComputerName,ActiveTime,IdleTime"') do @for /f "tokens=2" %q in ('"ping -a %n -n 1 find /i "pinging""') do @echo %q %user% %n %i %m %o&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Doskey macro to find session connection information for a user/workstation&lt;/u&gt;&lt;br /&gt;FU=for %g in ($1 $2 $3 $4 $5 $6 $7 $8 $9) do @for /f "tokens=2 delims=\" %i in ('"dsquery user -name %g dsget user -hmdir find /i "%g""') do @for /f "skip=1 tokens=1-3" %m in ('"wmic /node:"%i" path win32_serversession WHERE "UserName Like '%g'" Get ComputerName,ActiveTime,IdleTime"') do @for /f "tokens=2" %q in ('"ping -a %n -n 1 find /i "pinging""') do @echo %q %g %n %i %m %o&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Refresh per user settings such as desktop wallpaper&lt;/u&gt;&lt;br /&gt;RunDll32.exe USER32.DLL,UpdatePerUserSystemParameters ,1 ,True&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query RDP sessions on a 2003 server&lt;/u&gt;&lt;br /&gt;query session&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Shadow an existing TS or console session (Ctrl -* to end the shadow)&lt;/u&gt;&lt;br /&gt;shadow %session%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run a command in the winlogon secure desktop of winsta0\winlogon&lt;/u&gt;&lt;br /&gt;psexec /x /d /s cmd&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Remotely Run a command in the winlogon secure desktop of winsta0\winlogon&lt;/u&gt;&lt;br /&gt;psexec /s \\%computer% cmd /c c:\windows\temp\psexec /x /d /s cmd&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Update the wallpaper on the winlogon secure desktop winsta0\winlogon&lt;/u&gt;&lt;br /&gt;psexec /accepteula /x /s RunDll32.exe USER32.DLL,UpdatePerUserSystemParameters&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Run commands automatically when a command prompt is started&lt;/u&gt;&lt;br /&gt;reg add "hklm\software\microsoft\Command Processor" /v AutoRun /t reg_sz /d "doskey /macrofile=macros.txt"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Export the groups a user in eDirectory is a member of&lt;/u&gt;&lt;br /&gt;ldifde -f output.txt -s %NetwareServer% -a "%AccountDN%" * -d %rootDN% -r "(&amp;amp;(Objectclass=user)(((cn=User1)(cn=User2))))" -l cn,groupMembership&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Produce a list of files that should be purged based in minage&lt;/u&gt;&lt;br /&gt;robocopy /l %Source% %Temp%\Purge%Random% *.* /minage:6 /FP /NJS /NJH /E /TS /NS&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the install date from a list of servers&lt;/u&gt;&lt;br /&gt;for %i in (%Server1% %Server2%) do psinfo \\%i 2&amp;gt;nul findstr /i /c:"Install date" /c:"%ComputerName%"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use findstr with regular expressions to find start of line + space + 'New Dir'&lt;/u&gt;&lt;br /&gt;findstr /i "^.*New.Dir" Dirs.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Use delayed environment varialble substitution in a for loop&lt;/u&gt;&lt;br /&gt;for /f "delims=:" %i in ('"findstr /i /n "^.*New.Dir" PurgeFiles.txt"') do Set Directory=0000%i &amp;amp; Echo !Directory:~-5!&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query Windows Update logs from contactable machines in an OU&lt;/u&gt;&lt;br /&gt;for /f %i in ('"dsquery computer %DN% -o rdn"') do @for /f "tokens=3 delims=: " %m in ('"ping -n 1 %i find /i "reply from""') do dumpel -s %i -l system -e 19 20 -m "Windows Update Agent"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Produce a flat list of files, with the last-write date&lt;/u&gt;&lt;br /&gt;dir %Directory% /tw/s find /i "/" find /i /v "DIR" &amp;gt; Output.txt&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a control file and a text file, output control entries that aren't found&lt;/u&gt;&lt;br /&gt;for /f "tokens=1-3" %i in (%ControlFile%) do @find /i "%i" %TextFile% &amp;gt;NUL &amp;amp; @if errorlevel 1 echo %i&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Given a control file and a text file, show whether or not control is in text&lt;/u&gt;&lt;br /&gt;for /f "tokens=1-3" %i in (%ControlFile%) do @find /i "%i" %TextFile% &amp;gt;NUL &amp;amp; @if errorlevel 0 if not errorlevel 1 (echo %i Member) else (echo %i NotMember)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query a specific eDirectory group for its members&lt;/u&gt;&lt;br /&gt;ldifde -f output.txt -s %NetwareServer% -a "%AccountDN%" * -d %rootDN% -l cn,member&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Export a Operations Manager 2007 sealed management pack to an unsealed XML&lt;/u&gt;&lt;br /&gt;. c:\windows\temp\MpToXml.ps1 "%SealedMP%.mp" c:\windows\temp&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Join output split across two lines using delayed variable expansion (cmd /v:on)&lt;/u&gt;&lt;br /&gt;for /f "tokens=3,4" %i in ('"findstr /i /c:"printDuplexSupported" /c:"Share Name" PrintersRegQuery.txt"') do @if "%i"=="REG_SZ" (@Set Printer=%j) else (@Echo !Printer!,%i)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Open an Excel document in read-only mode from the commandline&lt;/u&gt;&lt;br /&gt;start excel /h /e %xls%&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Extract B if A is found in B, otherwise report blank&lt;/u&gt;&lt;br /&gt;for /f "tokens=1-3 delims=," %i in (a.txt) do @find /i "%i" b.csv &amp;gt;nul &amp;amp; If errorlevel 0 if not errorlevel 1 (for /f "tokens=4 delims=," %m in ('"find /i "%i" b.csv find /i "%i""') do @echo %i,%m,%j,%k) else (Echo %i,none,%j,%k)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query SMS for computers on a particular subnet&lt;/u&gt;&lt;br /&gt;wmic /namespace:\\root\sms\site_%sitecode% /node:"%site_Server%" path SMS_R_System WHERE "IPSubnets='%subnet%' AND Active=1'" get name&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Query SMS for computers in a specific AD site&lt;/u&gt;&lt;br /&gt;wmic /namespace:\\root\sms\site_%sitecode% /node:"%site_Server%" path SMS_R_System WHERE "ADSiteName='BNE' AND Active=1'" get name&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find the owner of a process using WMI - see who's logged on remotely&lt;/u&gt;&lt;br /&gt;wmic /node:"%computer%" PROCESS where "caption='explorer.exe'" getowner&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Convert a file to/from base64 to transmit a binary file through filters&lt;/u&gt;&lt;br /&gt;http://www.motobit.com/util/base64-decoder-encoder.asp&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Disable path parsing when listing a directory&lt;/u&gt;&lt;br /&gt;dir "\\?\c:\folder"&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Find network information for a computer from SMS&lt;/u&gt;&lt;br /&gt;wmic /namespace:\\root\sms\site_%sitecode% /node:"%siteserver%" path  SMS_R_System WHERE Name='%computer%' get name,adsitename,IPAddresses,IPSubnets,MACAddresses&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Send a Wake-on-lan magic packet on a local subnet&lt;/u&gt;&lt;br /&gt;wolcmd 00157283E57F 192.168.0.10 255.255.255.0 7&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Get the lanmanserver description using SNMP&lt;/u&gt;&lt;br /&gt;Snmputil.exe get %server% %community% .iso.org.dod.internet.private.enterprises.lanmanager.lanmgr-2.server.svDe
