Learn about Windows PowerShell
Summary: Microsoft Scripting Guy, Ed Wilson, discusses using the DISM module in Windows 8 to work with desktop settings.
Microsoft Scripting Guy, Ed Wilson, is here. The Scripting Wife and I are looking forward to the Central Ohio PowerShell User Group (COPUG) in Columbus, Ohio next week. We have not been back to Columbus since we were there for the first Windows PowerShell Saturday event. We both enjoy Columbus, and we are looking forward to spending some time with Wes Stahler and the other members of the group.
One of the things in Windows 8 that I enjoy messing around with is the DISM module. Now, one might think that to use the DISM module requires advanced knowledge of Windows Imaging, XML, and various deployment technologies. To be sure, some or all of that level of specialization would come in handy, but I like the low hanging fruit of being able to get stuff. The secret of this approach lies in knowing that there is an Online switch.
Note The DISM cmdlets require administrative rights.
One of the confusing things about cmdlets from the DISM module is that they all seem to want the path to a Windows image—and what that image is supposed to be is anyone’s guess. The secret to immediate productivity lies in knowing that I can use the Online switch to work with my current Windows 8 installation. By this, I mean that I can use Online and work directly with my laptop.
Note This does not mean that I am limited to working only with my local computer. Even though there is no ComputerName parameter, I can place my DISM module cmdlets inside Invoke-Command, and then use Windows PowerShell remoting to run the commands on remote systems. This secret enables extremely powerful remote management scenarios.
To identify which edition of Windows 8 I am running on my laptop, I use the Get-WindowsEdition cmdlet as shown here.
PS C:\> Get-WindowsEdition -Online
Edition : Professional
More information than just the edition returns from the cmdlet. To display the additional information I pipe the results to the Format-List cmdlet. This command is shown here (fl is an alias for the Format-List cmdlet).
PS C:\> Get-WindowsEdition -Online | fl *
Path :
Online : True
WinPath :
SysDrivePath :
RestartNeeded : False
LogPath : C:\WINDOWS\Logs\DISM\dism.log
ScratchDirectory :
LogLevel : WarningsInfo
I can use dotted notation to access specific properties from EditionObject. For example, I can determine if I have a restart pending by retrieving the RestartNeeded property. This is shown here.
PS C:\> (Get-WindowsEdition -Online).restartneeded
False
After I know that, I can determine if the laptop requires a restart, and I can easily create a command to reboot the machine if a restart pends. The following code restarts the laptop if RestartNeeded returns True.
if((Get-WindowsEdition -Online).restartneeded) {Restart-Computer}
I like to use the Get-Command cmdlet to find all the cmdlets that are supplied by a module. To find the cmdlets exposed by the DISM module, I use the command shown here.
PS C:\> Get-Command -Module dism -CommandType cmdlet
CommandType Name ModuleName
----------- ---- ----------
Cmdlet Add-AppxProvisionedPackage Dism
Cmdlet Add-WindowsDriver Dism
Cmdlet Add-WindowsPackage Dism
Cmdlet Clear-WindowsCorruptMountPoint Dism
Cmdlet Disable-WindowsOptionalFeature Dism
Cmdlet Dismount-WindowsImage Dism
Cmdlet Enable-WindowsOptionalFeature Dism
Cmdlet Get-AppxProvisionedPackage Dism
Cmdlet Get-WindowsDriver Dism
Cmdlet Get-WindowsEdition Dism
Cmdlet Get-WindowsImage Dism
Cmdlet Get-WindowsOptionalFeature Dism
Cmdlet Get-WindowsPackage Dism
Cmdlet Mount-WindowsImage Dism
Cmdlet Remove-AppxProvisionedPackage Dism
Cmdlet Remove-WindowsDriver Dism
Cmdlet Remove-WindowsPackage Dism
Cmdlet Repair-WindowsImage Dism
Cmdlet Save-WindowsImage Dism
Cmdlet Set-WindowsEdition Dism
Cmdlet Set-WindowsProductKey Dism
Cmdlet Use-WindowsUnattend Dism
After I know the cmdlets provided by the DISM module, I can determine if I want to get information or if I want to set information. For now, I am exploring; therefore, I am more interested in getting information than in setting information.
Drivers are always an issue. Good drivers make hardware sing, bad drivers are something of a challenge. When I find drivers that make my hardware work properly, I need to examine the other computers to ensure they are using the same version of the driver. One thing I often pay attention to are devices that are using the default Microsoft driver. At times this is a good thing (due to compatibility issues); but sometimes it indicates that I have simply not updated the system.
The following command lists the Microsoft drivers that are used on my laptop. If I do not use the All parameter, I receive information about default drivers. If I do not use the All parameter, only non-Microsoft drivers are listed.
Get-WindowsDriver -Online –all | where providername -match 'microsoft'
The command and associated output are shown in the image that follows.
One thing to pay attention to when working with these cmdlets is that unlike most cmdlets where “what you see is what you need to use,” the DISM team decided to break up the property names into different display names. A quick check of the Get-Member cmdlet reveals the property names required when working with these cmdlets.
PS C:\> Get-WindowsDriver -Online | gm -MemberType *property
TypeName: Microsoft.Dism.Commands.BasicDriverObject
Name MemberType Definition
---- ---------- ----------
BootCritical Property bool BootCritical {get;set;}
Build Property uint32 Build {get;set;}
CatalogFile Property string CatalogFile {get;set;}
ClassDescription Property string ClassDescription {get;set;}
ClassGuid Property string ClassGuid {get;set;}
ClassName Property string ClassName {get;set;}
Date Property datetime Date {get;set;}
Driver Property string Driver {get;set;}
DriverSignature Property Microsoft.Dism.Commands.DriverSignature DriverSig...
Inbox Property bool Inbox {get;set;}
LogLevel Property Microsoft.Dism.Commands.LogLevel LogLevel {get;set;}
LogPath Property string LogPath {get;set;}
MajorVersion Property uint32 MajorVersion {get;set;}
MinorVersion Property uint32 MinorVersion {get;set;}
Online Property bool Online {get;set;}
OriginalFileName Property string OriginalFileName {get;set;}
Path Property string Path {get;set;}
ProviderName Property string ProviderName {get;set;}
RestartNeeded Property bool RestartNeeded {get;set;}
Revision Property uint32 Revision {get;set;}
ScratchDirectory Property string ScratchDirectory {get;set;}
SysDrivePath Property string SysDrivePath {get;set;}
WinPath Property string WinPath {get;set;}
Version ScriptProperty System.Object Version {get="{0}.{1}.{2}.{3}" -f $...
That is all there is to using cmdlets from the DISM module. Join me tomorrow when I will talk about more cool Windows PowerShell 3.0 stuff.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy
Hi Ed,
this looks very neat ... at least, if you are running WIN8 ...
As I'm not (win7 x64 Enterprise), I can't try it out, but what I did anyway, is: I tried to run the command: "Get-WindowsEdition -Online" and, having set the ExecutionPolicy to unrestricted (I know that this is not recommended) ... I'm getting a lot of popups: "Security warning: Do you really want to run I:\windosPowerShell\Modules\....\...psm1" ?"
This continues until it finds "Get-WindowsEdition" in "PowerShellPack" which is of course not the same command.
I'm just wondering why PowerShell scans the "PSModulePath" and tries to find "Get-WindowsEdition" at all ... ?!
Klaus.
Great article ! Helpful. Thanks
Hi Ed, when are the scripting guys going to publish a DISM GUI Front End, I'm sure you can slap together something more polished the this.
www.msfn.org/.../138804-mr-jinje-dism-tool
@K_Schulte sounds like you are running Windows PowerShell 3.0. Windows PowerShell 3.0 automatically searches the module path to find cmdlets. It does this so you do not have to load a module prior to using the cmdlet. It is a great time saver to be able to run a cmdlet without having to first load the module. When PowerShell finds the cmdlet, it loads the module for you, then runs the command.
@Santosh Bhandarkar thank you, I am glad you found it helpful.
@Knuckle-Dragger it will not happen. I do not have the time to do those sort of things. I prefer to spend my time focusing on writing great content for the Hey Scripting Guy blog, speaking at user groups and conferences and working with the community.
Good Article.
AH! Right!!
I read about this feature but didn't notice it up to now!
Having set my Executionpolicy to unrestricted shows the effect of this automatic search in PS 3.0
You see the warning message box while PS 3.0 is still searching for a module containing the desired command.
It does so until it has found the command ..... or not :-)
Not a problem Ed, it was worth a shot. Keep up the good works.