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"
    }

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

   
© 2011 Posh TipsSuffusion theme by Sayontan Sinha

Page optimized by WP Minify WordPress Plugin