Update (8/22/2011): Since you’re looking at WMI Query stuff, you may want to check out my newer GetHostInfo utility.
My previously posted get-wmidata script had a serious shortcoming in that the user was required to pass login credentials to authenticate on a remote server. Since the WMI call interface will use your existing logged-in credentials, the -USER parameter in the original script should be (and now is) optional. The new behavior of this script is to use your existing (logged-on) credentials if the -USER parameter is not passed. Additionaly, several other WMI classes were added and (due to the volume of data) the script no longer produces CSV formatted output.
Another update was made to query various additional WMI classes and provide a (somewhat) formated output. Format-Table is used where multiple rows are returned, otherwise Format-List is used. This brings me to a new discovery (and apparent quirk) with Windows PowerShell that exists in both versions 1 and 2. Apparently, the output streams can get confused within a script when repeatedly using Format-Table resulting in the following error message:
out-lineoutput : Object of type "Microsoft.PowerShell.Commands.Internal.Format.FormatStartData" is not legal or not in the correct sequence. This is likely caused by a user-specified "format-table" command which is conflicting with the default formatting.Interestingly, this error only occurs when executed within a script and does not occur when running interactively via the PowerShell console.
The workaround is very simple: send the “Format-Table” output to “Out-Default” via the pipeline. You will see this used extensively in the “GetWmiData” function. If you remove the “| Out-Default” code from this function, you can see the error message.
One final note, you will see that some of the numerical output is not in the most user-friendly format. For example disk capacity is shown in bytes where GigaBytes would probably be a more practical measurement. Anyway, that’s a subject for another posting; for now, here’s a handy WMI script with the ability to process a list of hosts and utilize passed user credentials.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 | $psScriptName = "get-wmidata.ps1" $psScriptAuth = "Kahuna at PoshTips.com" $psScriptDate = "11/30/2009" ############################################################################## ## Get-Wmidata.ps1 - powershell script template ## ## Original Script by Kahuna at PoshTips.com - 11/30/2009 ## ## Maintenance (most recent updates at top): ## Date By Comments ## ---------- --- ---------------------------------------------------------- ## 11/30/2009 KPS -USER is now an optional parameter - default will now use ## your logged-in credentials ## 11/24/2009 KPS new script ## ############################################################################## $scriptUsage = @" ============================================================================== SCRIPT : $psScriptName AUTHOR : $psScriptAuth VERSION : $psScriptDate ============================================================================== PURPOSE: powershell script to do WMI query on remote host(s) USAGE: Get-Wmidata hostname(s) | filename(s) [-User=][-?|-H] - From the PowerShell command-line, invoke the script, passing any combination of hostnames and filenames (text file(s) containing a hostname listing - Any combinations and number of arguments can be used - if an argument is a filename: - each line in the file will processed as a hostname - any lines starting with `# will be treated as comments and ignored - if an argument is not a filename: - the argument will processed as a hostname FLAGS: -USER = A local user account or fully-qualified (domain) user account Note: If ommitted, your current logged-on credentials will be used -? or -H = Display this help EXAMPLES: ./Get-Wmidata server1 hostlist.txt -USER=administrator ./Get-Wmidata server1 hostlist.txt -USER=poshtips\kahuna ./Get-Wmidata server1 hostlist.txt ============================================================================== "@ Set-PSDebug -Trace 0 $script:recCount = 0 $script:usr = "" $script:pwd = "" $script:DOMACCT = 1 $script:LOCACCT = 2 $script:acctType = 0 $script:credentials = "" function ShowUsage([string]$message=""){ $message $scriptUsage exit } function CurrentAcctType { switch ($script:acctType){ $script:LOCACCT {return "LOCAL"; break;} $script:DOMACCT {return "DOMAIN"; break;} default {return "????"; break;} } } function GetPassword(){ $prompt = ([string]::format("Enter the password for {0} account ""{1}"" ",(CurrentAcctType),$script:usr)) $script:pwd = read-host -assecurestring $prompt if ($script:acctType -eq $script:DOMACCT) { $script:credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $script:usr, $script:pwd } } function WmiQueryHeading($hostname,$class) { "--------------------------------------------------------" "$hostname ($class)" } function GetWmiData($hostname) { "*******************************************************************" "*** HOST: $hostname" "*******************************************************************" if ($script:usr -ne ""){ if ($script:acctType -eq $script:LOCACCT) { $localusername = [string]::Format("{0}\\{1}",$hostname,$script:usr) $script:credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $localusername, $script:pwd } WmiQueryHeading $hostname "win32_ComputerSystem" gwmi -credential $script:credentials -computer $hostname win32_computersystem | select Name,Domain,Description,Manufacturer,Model,Status,SystemType,TotalPhysicalMemory | fl |out-default WmiQueryHeading $hostname "win32_Processor" gwmi -credential $script:credentials Win32_Processor -computer $hostname | select SocketDesignation,Caption,CurrentClockSpeed,ExtClock,Family,L2CacheSize,AddressWidth | ft -autosize |out-default WmiQueryHeading $hostname "win32_OperatingSystem"; gwmi -credential $script:credentials Win32_OperatingSystem -computer $hostname |out-default WmiQueryHeading $hostname "win32_LogicalDisk" gwmi -credential $script:credentials -query "SELECT * from Win32_LogicalDisk WHERE DriveType=3" -computer $hostname | select DeviceId,FreeSpace,Size | ft -autosize |out-default WmiQueryHeading $hostname "win32_PhysicalMemory" gwmi -credential $script:credentials Win32_PhysicalMemory -computer $hostname | select DeviceLocator,Capacity,DataWidth,Speed | ft -autosize |out-default WmiQueryHeading $hostname "win32_NetworkAdapter" gwmi -credential $script:credentials -query "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus=2" -computer $hostname | select MACAddress,AdapterType,DeviceId,Name | ft -autosize |out-default WmiQueryHeading $hostname "win32_NetworkAdapterConfiguration" gwmi -credential $script:credentials -query "SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled='True'" -computer $hostname | select DHCPEnabled,IPAddress,DefaultIPGateway,ServiceName,Description,Index | ft -autosize| out-default } else { #yes, I know this is repeated code from above with "-credentials" removed #(ugly, but a workaround to modularize did not come to me right away) WmiQueryHeading $hostname "win32_ComputerSystem" gwmi win32_computersystem -computer $hostname | select Name,Domain,Description,Manufacturer,Model,Status,SystemType,TotalPhysicalMemory | fl |out-default WmiQueryHeading $hostname "win32_Processor" gwmi Win32_Processor -computer $hostname | select SocketDesignation,Caption,CurrentClockSpeed,ExtClock,Family,L2CacheSize,AddressWidth | ft -autosize |out-default WmiQueryHeading $hostname "win32_OperatingSystem"; gwmi Win32_OperatingSystem -computer $hostname |out-default WmiQueryHeading $hostname "win32_LogicalDisk" gwmi -query "SELECT * from Win32_LogicalDisk WHERE DriveType=3" -computer $hostname | select DeviceId,FreeSpace,Size | ft -autosize |out-default WmiQueryHeading $hostname "win32_PhysicalMemory" gwmi Win32_PhysicalMemory -computer $hostname | select DeviceLocator,Capacity,DataWidth,Speed | ft -autosize |out-default WmiQueryHeading $hostname "win32_NetworkAdapter" gwmi -query "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus=2" -computer $hostname | select MACAddress,AdapterType,DeviceId,Name | ft -autosize |out-default WmiQueryHeading $hostname "win32_NetworkAdapterConfiguration" gwmi -query "SELECT * FROM Win32_NetworkAdapterConfiguration where IPEnabled='True'" -computer $hostname | select DHCPEnabled,IPAddress,DefaultIPGateway,ServiceName,Description,Index | ft -autosize |out-default } } ###################################################### ## MAIN ###################################################### if ($args.count -ge 1) { # Process command-line flags foreach ($item in $args) { if ($item -like "-USER=*"){ $script:usr = ($item.split("=")[1]) if ($script:usr -like "*\*"){$script:acctType = $script:DOMACCT} else {$script:acctType = $script:LOCACCT} } elseif ($item -like "-*"){ switch ($item){ "-H" {ShowUsage;} "-?" {ShowUsage;} default { if ($item -like "-USER=*") { ShowUsage "ERROR: $item is invalid!"; } } } } } if ($script:usr -eq ""){ #ShowUsage "ERROR: -USER flag is required" } else { GetPassword } # Process non-flag arguments foreach ($item in $args) { if ($item -notlike "-*") { # if argument is filename: process file contents if (test-path($item)){ foreach ($hostname in get-content $item){ $hostname = $hostname.trim() if ($hostname -notlike "#*") { GetWmiData $hostname } } } # else treat as hostname else{ GetWmiData $item } } } } else { ShowUsage "ERROR: This script requires arguments" } |
Recent Comments