PowerShell for Windows Admins


December 17, 2013  3:06 AM

Deal of the Day–17 December 2013

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Manning – www.manning.com – have multiple PowerShell books as their deal of the day – today and tomorrow. The deal started at midnight ET today ( 3am GMT) and lasts for 48 hours.   Books included:

PowerShell and WMI

PowerShell in Practice

PowerShell in Depth

PowerShell Deep Dives

Windows PowerShell in Action, Second Edition

Learn PowerShell 3 in a Month of Lunches, Second Edition

Learn PowerShell Toolmaking in a Month of Lunches.

Get 50 % off these titles today and tomorrow with code dotd1217au

December 16, 2013  2:31 PM

A new version of ADMT

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A new version of the AD Migration Tool (ADMT) has been announced – http://blogs.technet.com/b/askds/archive/2013/12/13/an-update-for-admt-and-a-few-other-things-too.aspx

While not ready for download just yet at least we know its in the pipeline and supports the newer versions of Windows

 


December 16, 2013  2:20 PM

CDXML–adding search parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Last time you saw how to create a cmdlet from the Win32_NetWorkAdapterConfiguration class:

<?xml version=’1.0′ encoding=’utf-8′?>

<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>

<Class ClassName=’ROOT\cimv2\Win32_NetworkAdapterConfiguration’>

<Version>1.0</Version>

<DefaultNoun>NetworkAdapterConfiguration</DefaultNoun>

<InstanceCmdlets>

<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>

</GetCmdletParameters>

</InstanceCmdlets>

</Class>

</PowerShellMetadata>

 

Now its time to add some parameters that can be used for searching. This will be equivalent to performing these actions:

 

Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter “DHCPEnabled=’True’”

Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter “IPEnabled=’True’”

Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter “Index=0″

Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration -Filter “InterfaceIndex=3″

 

Lets start by looking at the DHCPEnabled property

£> $class = Get-CimClass -ClassName Win32_NetworkAdapterConfiguration

£> $class.CimClassProperties["DHCPEnabled"]

Name                            : DHCPEnabled

Value                             :

CimType                       : Boolean

Flags                              : Property, ReadOnly, NullValue

Qualifiers                      : {MappingStrings, read}

ReferenceClassName :

The parameter DHCPEnabled takes a Boolean value. At the moment I don’t want anything clever like pipeline input – just the ability to use a parameter

 

This requirement translates to:

<?xml version=’1.0′ encoding=’utf-8′?>

<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>

<Class ClassName=’ROOT\cimv2\Win32_NetworkAdapterConfiguration’>

<Version>1.0</Version>

<DefaultNoun>NetworkAdapterConfiguration</DefaultNoun>

<InstanceCmdlets>

<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>

 

<QueryableProperties>

<Property PropertyName=”DHCPEnabled”>

<Type PSType = “System.Boolean”/>

<RegularQuery >

<CmdletParameterMetadata PSName=”DHCPEnabled” />

</RegularQuery>

</Property>

 

</QueryableProperties>

 

</GetCmdletParameters>

</InstanceCmdlets>

</Class>

</PowerShellMetadata>

 

The changes are defined by the <QueryableProperties> tags

<QueryableProperties>

 

Define the WMI property you are searching on

<Property PropertyName=”DHCPEnabled”>

Define the type of the data the parameter accepts

<Type PSType = “System.Boolean”/>

Define the query type – in this case a straight forward search

<RegularQuery >

 

Define the name you want the parameter to have – doesn’t have to match the WMI property name

<CmdletParameterMetadata PSName=”DHCPEnabled” />

</RegularQuery>

</Property>

 

</QueryableProperties>

You can use the changed cmdlet like this:

Get-NetworkAdapterConfiguration

Get-NetworkAdapterConfiguration -DHCPEnabled $true

Get-NetworkAdapterConfiguration -DHCPEnabled $false

 

The full syntax on the cmldet is:

Get-NetworkAdapterConfiguration [-DHCPEnabled <bool[]>]

[-CimSession <CimSession[]>] [-ThrottleLimit <int>]

[-AsJob] [<CommonParameters>]

 

The cmdlets over objects technology automatically adds these parameters:

-CimSession

-ThrottleLimit

-AsJob

-CommonParameters

 

Next time we’ll add the other search properties

 


December 15, 2013  9:18 AM

CDXML–network adapter configuration

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve amended the new-cdxml function created earlier in the series:

function new-cdxml {

[CmdletBinding()]

param (

[Parameter(Mandatory=$true)]

[string]$class,

[Parameter(Mandatory=$true)]

[string]$noun,

[string]$namespace = ‘ROOT\cimv2′,

[string]$path = “C:\Scripts\Modules\Hardware”

)

$code = @”

<?xml version=’1.0′ encoding=’utf-8′?>

<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>

<Class ClassName=’$namespace\$class’>

<Version>1.0</Version>

<DefaultNoun>$noun</DefaultNoun>

<InstanceCmdlets>

<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>

</GetCmdletParameters>

</InstanceCmdlets>

</Class>

</PowerShellMetadata>

“@

$file = Join-Path -Path $path -ChildPath “$class.cdxml”

Write-Verbose -Message $file

Set-Content -Path $file -Value $code

}

The change is making the class and noun parameters mandatory. In PowerShell 3 & 4 you can simplify the syntax slightly:

param (

[Parameter(Mandatory)]

[string]$class,

[Parameter(Mandatory)]

[string]$noun,

[string]$namespace = ‘ROOT\cimv2′,

[string]$path = “C:\Scripts\Modules\Hardware”

)

I prefer to use the PowerShell 2.0 syntax and actually state that Mandatory=$true. This is for 2 reasons. Firstly, its what I’m used to and it works – I haven’t got round to changing my default templates. Secondly, I prefer to use this syntax because its immediately apparent to me that the parameter is Mandatory.

This time I’ve used the Win32_NetworkAdapterConfiguration class because it enables me to introduce the use of search (filter) parameters in CDXML cmdlets; it has a number of very useful methods and it enables me to introduce the use of format files.

Using new-cdxml you can create the basic module

<?xml version=’1.0′ encoding=’utf-8′?>

<PowerShellMetadata xmlns=’http://schemas.microsoft.com/cmdlets-over-objects/2009/11′>

<Class ClassName=’ROOT\cimv2\Win32_NetworkAdapterConfiguration’>

<Version>1.0</Version>

<DefaultNoun>NetworkAdapterConfiguration</DefaultNoun>

<InstanceCmdlets>

<GetCmdletParameters DefaultCmdletParameterSet=’DefaultSet’>

</GetCmdletParameters>

</InstanceCmdlets>

</Class>

</PowerShellMetadata>

To add this into the module manifest amend these two lines as shown:

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess

NestedModules = @(‘Win32_BIOS.cdxml’,

‘Win32_ComputerSystem.cdxml’,

‘Win32_DiskDrive.cdxml’,

‘Win32_NetworkAdapterConfiguration.cdxml’

)

# Functions to export from this module

FunctionsToExport = @(‘Get-Bios’,

‘Get-ComputerSystem’,

‘Get-PhysicalDisk’,

‘Get-NetworkAdapterConfiguration’

)

You now have a hardware module consisting of:

£> Get-Command -Module Hardware

CommandType Name

———– —-

Function Get-Bios

Function Get-ComputerSystem

Function Get-NetworkAdapterConfiguration

Function Get-PhysicalDisk

The output from Get-NetworkAdapterConfiguration on my Windows 8.1 virtual machine looks like this:

ServiceName     DHCPEnabled      Index     Description

———–            ———–                —–         ———–

netvsc                False                         0              Microsoft Hyper-V Network Adapter

kdnic                 True                           1              Microsoft Kernel Debug Network Adapter

tunnel               False                          3              Microsoft ISATAP Adapter

netvsc               False                          4              Microsoft Hyper-V Network Adapter #2

tunnel               False                          5              Microsoft ISATAP Adapter

Now this is the same display that Get-CimInstance produces and for my purposes it doesn’t work. I need to create a format file to produce the display I need. I also want to be able to filter on various criteria including DHCPEnabled, IPEnabled, InterfaceIndex, Index and Description. I also want to be able to search on any of these individually or in any logical combination


December 13, 2013  2:09 PM

Manning offer for Monday 16 December 2013

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

On Monday 16 December Manning are offering 50% off all ebooks using code dot1216au at www.manning.com

Check http://deals.manningpublications.com/countdown2014.html for other deals between now and the end of the year


December 12, 2013  9:00 AM

Deleting domain specific profiles

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I had a question regarding these posts:

http://msmvps.com/blogs/richardsiddaway/archive/2012/06.aspx

http://msmvps.com/blogs/richardsiddaway/archive/2013/12/10/1810778.aspx

The question came from someone needing to clean up a set of domain specific profiles.

You can adapt the code in the articles to identify the domain specific profiles like this:

$domain = “mydomain”
Get-CimInstance -ClassName Win32_UserProfile -Filter “Special = ‘$false’” |
select LocalPath, SID, LastUseTime,
@{N=”User”; E={Get-CimInstance -Class Win32_UserAccount -Filter “SID = ‘$($_.SID)’” | select -ExpandProperty Caption}} |
where User -Like “$domain\*”

Once you’ve identified them and ensured that your filters are giving you the correct results you can run this:

$domain = “mydomain”
Get-CimInstance -ClassName Win32_UserProfile -Filter “Special = ‘$false’” |
select LocalPath, SID, LastUseTime,
@{N=”User”; E={Get-CimInstance -Class Win32_UserAccount -Filter “SID = ‘$($_.SID)’” | select -ExpandProperty Caption}} |
where User -Like “$domain\*” |
foreach {
Get-CimInstance -ClassName Win32_UserProfile -Filter “SID = ‘$($_.SID)’” |
Remove-CimInstance -WhatIf

}

NOTICE I’ve left –whatif on the Remove-CimInstance.  It gives you an additional check before you finally commit to deleting the profiles

Alternatively, and better still, put the first set of code into an advanced function and then you can do this:

function get-domainprofile{
[CmdletBinding()]
param (
[string]$domain = “mydomain”
)
Get-CimInstance -ClassName Win32_UserProfile -Filter “Special = ‘$false’” |
select LocalPath, SID, LastUseTime,
@{N=”User”; E={Get-CimInstance -Class Win32_UserAccount -Filter “SID = ‘$($_.SID)’” | select -ExpandProperty Caption}} |
where User -Like “$domain\*”
}

get-domainprofile | foreach {
Remove-CimInstance -Query “Select * FROM Win32_UserProfile WHERE SID = ‘$($_.SID)’” -WhatIf
}

Again I’ve left –whatif in place. Remove it when you’re happy with the tests


December 11, 2013  1:57 PM

Final MEAP for AD Lunches

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The final MEAP for AD Management in a Month of Lunches has been released. The book is on a half price offer today so still time for a Christmas bargain if you’re quick

http://www.manning.com/siddaway3/


December 10, 2013  8:47 AM

December 11–Deal of the Day AD Month of Lunches

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Deal of the Day December 11:

Half off my book Learn Active Directory Management in a Month of Lunches.

Use code dotd1211au at www.manning.com/siddaway3/

Also available:

Learn SQL Server Administration in a Month of Lunches (www.manning.com/jones5/)

Learn SCCM 2012 in a Month of Lunches (www.manning.com/bannan/)


December 10, 2013  4:09 AM

Scripting Games countdown

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

The countdown to the 2014 Winter Scripting Games has started. The ideal way to brighten up the depths of winter.

This Games is for teams of least two. You can learn more by downloading and reading the players guide:

http://powershell.org/wp/2013/12/09/2014-winter-scripting-games-players-guide/

The games start January 2014 so don’t go looking for events just yet. Now would be a good time to look at the events from past games and get in some practice.


December 8, 2013  3:58 PM

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

On a Windows Server 2012 or 2012 R2 system you can install the ServerManager module and use the Get-WindowsFeature cmdlet to discover the installed features. They can be managed with Install-WindowsFeature and Uninstall-WindowsFeature .

These cmdlets don’t exist on Windows 8/8.1

However the Dism (Deployment Image Servicing and Management) module can help out. The Dism module is mainly concerned with managing wim files and virtual disks for deployment scenarios but it also contains these cmdlets:

Enable-WindowsOptionalFeature

Get-WindowsOptionalFeature

Disable-WindowsOptionalFeature

To discover the installed features

Get-WindowsOptionalFeature -Online | Format-Table –AutoSize

The output looks like this

FeatureName                                                             State

———–                                                                      —–

Microsoft-Hyper-V-All                                           Enabled

Microsoft-Hyper-V-Tools-All                                Enabled

Microsoft-Hyper-V                                                  Enabled

Microsoft-Hyper-V-Management-Clients           Enabled

Microsoft-Hyper-V-Management-PowerShell    Enabled

Printing-Foundation-Features                               Enabled

Printing-Foundation-LPRPortMonitor                Disabled

Printing-Foundation-LPDPrintService                 Disabled

Printing-Foundation-InternetPrinting-Client     Enabled

etc

For all of these cmdlets use –Online to access the local machine rather than an image.

Individual features can be enabled or disabled

Enable-WindowsOptionalFeature -FeatureName TelnetClient –Online

Disable-WindowsOptionalFeature -FeatureName TelnetClient –Online

Feature names are case sensitive.


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: