PowerShell for Windows Admins


January 15, 2010  3:49 PM

Mapping physical disks to logical drives

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We have looked at physical disks and logical disks. We know there is a relationship between them.

disk drive – partition – logical disk

In WMI this maps to.

Win32_DiskDrive – Win32_DiskPartition – Win32_LogicalDisk.DeviceID

We have two classes that provide the links

Win32_DiskDriveToDiskPartition and Win32_LogicalDiskToPartition which we can use like this

Get-WmiObject -Class Win32_DiskDriveToDiskPartition | Select Antecedent, Dependent

Get-WmiObject -Class Win32_LogicalDiskToPartition | Format-List Antecedent, Dependent

but we then have to match the information ourselves.  if we look at the information for the C: drive

Antecedent : \\RSLAPTOP01\root\cimv2:Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"
Dependent  : \\RSLAPTOP01\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"

Antecedent : \\RSLAPTOP01\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #1"
Dependent  : \\RSLAPTOP01\root\cimv2:Win32_LogicalDisk.DeviceID="C:"

we can see that we get antecedent and dependent pairs – we can access these associations directly using a WQL query to find the ASSOCIATORS.

PS> Get-WmiObject -Query "ASSOCIATORS OF {Win32_DiskDrive.DeviceID=’\\.\PHYSICALDRIVE0′} " | Select __CLASS -Unique

__CLASS
——-
Win32_PnPEntity
Win32_ComputerSystem
Win32_DiskPartition
Win32_PhysicalMedia

Shows us that we have a direct association between the Win32_DiskDrive class and the Win32_DiskPartition class. Next we have to work out how to get this information for all drives and all partitions

Technorati Tags: ,,

January 12, 2010  2:41 AM

Disks Part 4: Mount points

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We have seen how to discover our physical and logical disks.  In a quick digression I want to cover Mount Points.  These allow us to mount the volume into an empty folder in the file system rather than having a new drive. They are useful when we have lots of volumes and need to conserve drive letters.

001
002
003
004
005
006
007
008
009
010
Get-WmiObject -Class Win32_MountPoint | 
where {$_.Directory -like ‘Win32_Directory.Name="C:\\Data*"’} | 
foreach {
    $vol = $_.Volume
    Get-WmiObject -Class Win32_Volume | where {$_.__RELPATH -eq $vol} | 
    Select @{Name="Folder"; Expression={$_.Caption}}, 
    @{Name="Size (GB)"; Expression={"{0:F3}" -f $($_.Capacity / 1GB)}},
    @{Name="Free (GB)"; Expression={"{0:F3}" -f $($_.FreeSpace / 1GB)}},
    @{Name="%Free"; Expression={"{0:F2}" -f $(($_.FreeSpace/$_.Capacity)*100)}}
}

Our win32_MountPoint class only gives us directory and volume ID information.  if we want more we have to link to the Win32_Volume class.

As we know where we have mounted our volumes we can filter on that folder – note the use of c:\\data  – the \\ is a WMI syntax to escape the \.

For each mount point we find a volume with the correct ID.  I’ve use __RELPATH in the filter as it takes the same syntax as the ID in win32_mountpoint so we don’t need to do any processing.  Once we have our volume we can format the data in the way we have seen previously.

Technorati Tags: ,,


January 8, 2010  1:44 PM

Disks Part 3

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

We have seen how to use Win32_DiskDrive to look at our physical disks but this isn’t the whole story. We also need to consider logical disks or volumes

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
$dtype = DATA {
ConvertFrom-StringData -StringData @’
0 = Unknown
1 = No Root Directory
2 = Removable Disk
3 = Local Disk
4 = Network Drive
5 = Compact Disk
6 = RAM Disk
‘@

}

$media = DATA {
ConvertFrom-StringData -StringData @’
11 = Removable media other than floppy
12 = Fixed hard disk media
‘@

}

Get-WmiObject -Class Win32_LogicalDisk | 
Format-List DeviceID, Compressed, Description,
@{Name="Drive Type"; Expression={$dtype["$($_.DriveType)"]}},
@{Name="Media Type"; Expression={$media["$($_.MediaType)"]}},
FileSystem, 
@{Name="Disk Size (GB)"; Expression={"{0:F3}" -f $($_.Size/1GB)}},
@{Name="Free Space (GB)"; Expression={"{0:F3}" -f $($_.FreeSpace/1GB)}},
SupportsDiskQuotas,
SupportsFileBasedCompression,
VolumeName,
VolumeSerialNumber

We have a class called Win32_LogicalDisk for that. The properties are named so they are self explanatory. There are a couple of lookups to replace numeric values with text and a couple of calculations. 

When you run this notice that we get information for CD drives as well – but we don’t on the physical disks. One of the nice pieces of consistency in WMI!

The problem we face next is how to link our physical disk information with our logical disk information i.e. which logical disks are on which physical disk.

Technorati Tags: ,,


January 5, 2010  1:58 PM

Disks Part 2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

Moving swiftly on from last time we can expand the information returned on our disks

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
## Configuration Manager Error Code
$cmec = DATA {
ConvertFrom-StringData -StringData @’
0 = Device is working properly.
1 = Device is not configured correctly.
2 = Windows cannot load the driver for this device.
3 = Driver for this device might be corrupted, or the system may be low on memory or other resources.
4 = Device is not working properly. One of its drivers or the registry might be corrupted.
5 = Driver for the device requires a resource that Windows cannot manage.
6 = Boot configuration for the device conflicts with other devices.
7 = Cannot filter.
8 = Driver loader for the device is missing.
9 = Device is not working properly. The controlling firmware is incorrectly reporting the resources for the device.
10 = Device cannot start.
11 = Device failed.
12 = Device cannot find enough free resources to use.
13 = Windows cannot verify the device’s resources.
14 = Device cannot work properly until the computer is restarted.
15 = Device is not working properly due to a possible re-enumeration problem.
16 = Windows cannot identify all of the resources that the device uses.
17 = Device is requesting an unknown resource type.
18 = Device drivers must be reinstalled.
19 = Failure using the VxD loader.
20 = Registry might be corrupted.
21 = System failure. If changing the device driver is ineffective, see the hardware documentation. Windows is removing the device.
22 = Device is disabled.
23 = System failure. If changing the device driver is ineffective, see the hardware documentation.
24 = Device is not present, not working properly, or does not have all of its drivers installed.
25 = Windows is still setting up the device.
26 = Windows is still setting up the device.
27 = Device does not have valid log configuration.
28 = Device drivers are not installed.
29 = Device is disabled. The device firmware did not provide the required resources.
30 = Device is using an IRQ resource that another device is using.
31 = Device is not working properly. Windows cannot load the required device drivers.
‘@

}

Get-WmiObject -Class Win32_DiskDrive | 
Format-List DeviceID, Status, 
@{Name="Configuration Manager Error Code"; Expression={$cmec["$($_.ConfigManagerErrorCode)"]}},
Index, InterfaceType, 
Partitions, BytesPerSector, SectorsPerTrack, TracksPerCylinder,
TotalHeads, TotalCylinders, TotalTracks, TotalSectors,
@{Name="Disk Size (GB)"; Expression={"{0:F3}" -f $($_.Size/1GB)}}

Most of this script is taken up with defining the configuration error codes!

The other aspects are similar to our OS script.  Now we can know what our physical disks are like we need to look at the logical disks and incorporate that information to get the full story.

Once we have finished with this series on disks I’ll post the scripts so that they can be downloaded.

Technorati Tags: ,,


January 3, 2010  8:36 AM

Disks Part 1

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Disk storage and everything associated with that is a big part of administering our servers. We need to be able to discover, and where necessary, work with the storage system. WMI gives us a number of classes for working with disks

PS> Get-WmiObject -List Win32_*disk* | select name

Name
—-
Win32_LogicalDisk
Win32_MappedLogicalDisk
Win32_DiskPartition
Win32_DiskDrive
Win32_LogicalDiskRootDirectory
Win32_DiskQuota
Win32_LogonSessionMappedDisk
Win32_LogicalDiskToPartition
Win32_DiskDrivePhysicalMedia
Win32_DiskDriveToDiskPartition
Win32_PerfFormattedData_PerfDisk_LogicalDisk
Win32_PerfRawData_PerfDisk_LogicalDisk
Win32_PerfFormattedData_PerfDisk_PhysicalDisk
Win32_PerfRawData_PerfDisk_PhysicalDisk

PS> Get-WmiObject -List Win32_*volume* | select name

Name
—-
Win32_VolumeChangeEvent
Win32_Volume
Win32_VolumeQuota
Win32_VolumeQuotaSetting
Win32_VolumeUserQuota
Win32_ShadowVolumeSupport
Win32_ShadowDiffVolumeSupport

PS> Get-WmiObject -List Win32_*drive* | select name

Name
—-
Win32_DiskDrive
Win32_FloppyDrive
Win32_TapeDrive
Win32_CDROMDrive
Win32_DiskDrivePhysicalMedia
Win32_DiskDriveToDiskPartition

Note that the last list has been edited to exclude those classes to work with drivers

Our starting point has to be the physical drives.

PS> Get-WmiObject -Class Win32_DiskDrive

Partitions : 3
DeviceID   : \\.\PHYSICALDRIVE0
Model      : ST9250320AS ATA Device
Size       : 250056737280
Caption    : ST9250320AS ATA Device

 

As with the Operating System there is a lot of information behind this – details from http://msdn.microsoft.com/en-us/library/aa394132(VS.85).aspx

We’ll dig further into disks in the next series of posts

Technorati Tags: ,,


January 1, 2010  5:06 AM

Downloading PowerShell version 2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The PowerShell version 2 download seems to be difficult to find. It is part of the Windows Management Framework (PowerShell 2.0, WinRM 2.0 and (where applicable BITS 4.0).

The install packages for various Operating Systems – Vista, Windows 2008, Windows 2003 and Windows XP are available in 32 and 64 bit versions from

http://support.microsoft.com/kb/968929

BITS 4.0 is only supported on Windows 2008 & Vista

Happy New-Year


December 29, 2009  12:21 PM

Hotfixes

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

We have seen how to get information on the Operating System installed on our computers. We can round that out by looking at the hotfixes that are installed on the machine.

Get-WmiObject -Class Win32_QuickFixEngineering

Source        Description      HotFixID      InstalledBy          InstalledOn
——        ———–      ——–      ———–          ———–
RSLAPTOP01    Update           KB972636      RSLAPTOP01\Richard   08/07/2009 00:00:00
RSLAPTOP01    Security Update  KB973525      NT AUTHORITY\SYSTEM
RSLAPTOP01    Update           KB973874      NT AUTHORITY\SYSTEM
RSLAPTOP01    Update           KB974332      RSLAPTOP01\Richard
RSLAPTOP01    Update           KB974431      NT AUTHORITY\SYSTEM
RSLAPTOP01    Security Update  KB974455      NT AUTHORITY\SYSTEM
RSLAPTOP01    Security Update  KB974571      NT AUTHORITY\SYSTEM
RSLAPTOP01    Update           KB975364      RSLAPTOP01\Richard   11/01/2009 00:00:00
RSLAPTOP01    Hotfix           KB975467      NT AUTHORITY\SYSTEM
RSLAPTOP01    Update           KB976098      NT AUTHORITY\SYSTEM
RSLAPTOP01    Security Update  KB976325      NT AUTHORITY\SYSTEM  12/11/2009 00:00:00
RSLAPTOP01    Update           KB976749      RSLAPTOP01\Richard   11/04/2009 00:00:00

This displays all hotfixes. Sometimes we may just want to test for a single fix

Get-WmiObject -Class Win32_QuickFixEngineering -Filter "HotFixID=’KB972636′"

of for a set of machines

"RSLAPTOP01", "127.0.0.1" | foreach {
if (Get-WmiObject -Class Win32_QuickFixEngineering -Filter "HotFixID=’KB972636′")
{Write-Host "$($_) has KB972636 installed"}
}

With PowerShell v2 If we want to learn more about a particular fix we can do this

Get-WmiObject -Class Win32_QuickFixEngineering -Filter "HotFixID=’KB972636′" | foreach {Start-Process $_.caption}

The caption property conatins  a URL e.g. http://support.microsoft.com/?kbid=972636

A get-hotfix cmdlet has been introduced that simplifies this

Get-HotFix -Id KB972636 | foreach {Start-Process $_.Caption}

We have finished our look at the OS – next time we will start looking at disks.

Happy New Year

Technorati Tags: ,,


December 21, 2009  11:41 AM

Class Descriptions

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We have seen how to find the classes associated with a particular aspect of our system e.g.

Get-WmiObject  -List  *disk*

We will see this one again soon when we turn our attention to disks

One thing we can’t get directly is a description of the class so we can confirm it does what we think.  Well, with a little bit of digging in Powershell 2 we can use the –ammended parameter to display a description

PS> ((Get-WmiObject -List Win32_OperatingSystem -Amended).Qualifiers | Where {$_.Name -eq "Description"}).Value

The Win32_OperatingSystem class represents an operating system installed on a Win32 computer system. Any operating system that can be installed on a Win32 system is a descendent (or member) of this class.
Example: Microsoft Windows 95.

We list the class we are interested in and select the qualifiers. A where statement is used to filter for the description qualifier and then we display its value.

We don’t normally display the description because it is a more expensive operation.

Technorati Tags: ,,


December 21, 2009  7:23 AM

Working with the OS

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

We’ve seen what information we can derive on the Operating System from Win32_OperatingSystem but is there anything we can actually do to our systems?

There are a handful of methods available to us – mainly to do with shutting down the system

PS> Get-WmiObject -Class Win32_OperatingSystem | Get-Member -MemberType Method | Format-Table Name, Definition -Wrap

Name                                                  Definition
—-                                                        ———-
Reboot                                                System.Management.ManagementBaseObject Reboot()
SetDateTime                                     System.Management.ManagementBaseObject SetDateTime(System.S
                                                             tring LocalDateTime)
Shutdown                                           System.Management.ManagementBaseObject Shutdown()
Win32Shutdown                               System.Management.ManagementBaseObject Win32Shutdown(System
                                                             .Int32 Flags, System.Int32 Reserved)
Win32ShutdownTracker                 System.Management.ManagementBaseObject Win32ShutdownTracker
                                                             (System.UInt32 Timeout, System.String Comment, System.UInt3
                                                             2 ReasonCode, System.Int32 Flags)

Details from http://msdn.microsoft.com/en-us/library/aa394239(VS.85).aspx but

Reboot will shutdown and restart the system. SetDatetime ssts computer date and time (shouldn’t be needed with Time synchronisation in the domain)

Shutdown unloads programs and dlls so computer can be turned off

Win32Shutdown gives us options

0 (0×0) = Log Off
4 (0×4) = Forced Log Off (0 + 4)
1 (0×1) = Shutdown
5 (0×5) = Forced Shutdown (1 + 4)
2 (0×2) = Reboot
6 (0×6) = Forced Reboot (2 + 4)
8 (0×8) = Power Off
12 (0xC) = Forced Power Off (8 + 4)

On Vista\Win2008 and above we can use

Win32ShutdownTracker   to add a comment into the event log and and shutdown dialog box

We can use Win32Shutdown like this

$computer = Get-WmiObject -Class Win32_OperatingSystem -ComputerName .
$computer.Win32Shutdown(5)

If we put this into a loop and feed a set of computer names into it we can shut down our whole environment. Not a frequent occurrence – but one I needed to do recently when moving a datacentre.


December 19, 2009  7:13 AM

Using a script

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

 

We have seen how to use our script to access information on the local machine. Ideally we want to be accessing this information from many machines across our enterprise. If we save the script to get-os.ps1 we can use it in a few ways.

if we just want information on a handful of computers we can pipe them into the script like this.

".", "127.0.0.1", "rslaptop01" | foreach {"`n $_"; .\Get-OS.ps1 -computer $_ }

I’m running these scripts from the folder where I saved the script which is why I need ./ to represent the path of the current folder.  $_ is the object on the pipeline and `n is the way a new line is thrown.  A ; is used as a line terminator in PowerShell. It is only really used when we are typing at the prompt like this.

Import-Csv ./computers.csv | foreach { "`n"; $_.Computer ; .\Get-OS.ps1 -computer $_.Computer}

If we have a lot of computers – and we want to use the list in a number of scripts we can create a csv file. use a single column with a header of computer like this

Computer
.
localhost
127.0.0.1
rslaptop01

We can input computer names or IP addresses.

Now we know how to access information about our machine’s OS its time to see what else we can do.


Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: