PowerShell for Windows Admins


December 21, 2015  5:41 AM

JEA Helper Tool 2.0

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell, Windows Server 2016

JEA – Just Enough Admin – is a security feature in WMF 5.0 and Windows Server 2016 (TP4) – providing RBAC for your Windows servers. You can allow people to perform the tasks needed by their role without giving them full access.

An introductory document is available – https://gallery.technet.microsoft.com/Just-Enough-Administration-6b5ad370

Doing all this manually can be a bit overwhelming. The JEA helper Tool can ease this work. Version 2.0 is know available for download – details from http://blogs.technet.com/b/privatecloud/archive/2015/12/20/introducing-the-updated-jea-helper-tool.aspx

 

December 20, 2015  9:10 AM

Scripting Guy gets Pestered

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The Scripting Guy blog has been running a series on Pester written by Dave Wyatt – the modules author.

Pester provides a way to perform, and automate, testing on your PowerShell code.

The series is:

http://blogs.technet.com/b/heyscriptingguy/archive/2015/12/14/what-is-pester-and-why-should-i-care.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2015/12/15/getting-started-with-pester.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2015/12/16/unit-testing-powershell-code-with-pester.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2015/12/17/testing-script-modules-with-pester.aspx

http://blogs.technet.com/b/heyscriptingguy/archive/2015/12/18/more-pester-feature-and-resources.aspx


December 20, 2015  9:00 AM

New ScriptAnalyzer

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

A new version of Script Analyzer is available for download – http://blogs.msdn.com/b/powershell/archive/2015/12/17/scriptanalyzer-v1-2-0-released.aspx

A number of the rules have been updated and some new ones added


December 19, 2015  5:47 AM

WMF 5.0 RTM for Windows 8.1 and Windows 7

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The PowerShell Team blog http://blogs.msdn.com/b/powershell/archive/2015/12/16/windows-management-framework-wmf-5-0-rtm-is-now-available.aspx

has been updated to show WMF is now available for

Windows 8.1

Windows 7 SP1

On the download center – https://www.microsoft.com/en-us/download/details.aspx?id=50395 –

You’ll see x86 versions of WMF 5.0 for Windows 8.1 and Windows 7

For the x64 versions you need to use the appropriate server version. For Windows 8.1 x64 use the Windows 2012 R2 download and for Windows 7 use the Windows 2008 R2 download.

Notice there isn’t any support for Windows 8. You’ll have to use the free upgrade to Windows 8.1

Windows 10 as of the November update is effectively at WMF 5.0 RTM version


December 18, 2015  12:53 PM

Inputting computer names

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Somehting I was writing yesterday started me thinking about the way you input a list of computer names to a cmdlet. Many cmdlets have a ComputerName parameter so knowing how to deal with this sort of input will help. There are a range of techniques.

One of the simplest approaches is to create your list as a variable and use the variable:

$servers = ‘SERVER02’, ‘W12R2SCDC01’, ‘W12R2SUS’, ‘W12R2DSC’, ‘W12R2TGT’, ‘W12R2WEB01’, ‘W12R2WEB02’, ‘W12R2OD01’
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $servers

If you don’t need the server list as a variable then input it directly to the cmdlet

Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName ‘SERVER02’, ‘W12R2SCDC01’, ‘W12R2SUS’, ‘W12R2DSC’, ‘W12R2TGT’, ‘W12R2WEB01’, ‘W12R2WEB02’, ‘W12R2OD01’

The drawback is that the list of machine names is embedded in your code. The variable approach above is easier to maintain

A common approach is to use Foreach-Object

$servers = ‘SERVER02’, ‘W12R2SCDC01’, ‘W12R2SUS’, ‘W12R2DSC’, ‘W12R2TGT’, ‘W12R2WEB01’, ‘W12R2WEB02’, ‘W12R2OD01’
$servers | foreach {Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $psitem}

This works but adds unnecessary code. If you are performing other tasks in the foreach processing it may be worthwhile

Likewise using a foreach loop

$servers = ‘SERVER02’, ‘W12R2SCDC01’, ‘W12R2SUS’, ‘W12R2DSC’, ‘W12R2TGT’, ‘W12R2WEB01’, ‘W12R2WEB02’, ‘W12R2OD01’
foreach ($server in $servers) {
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $server
}

The foreach loop will be quicker but use more memory.

If you create a CSV file make sure you use ComputerName as the field header – then you can do this

Import-Csv .\computers.csv |
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’

if the header is something else – eg computer – then you need to use foreach-object

Import-Csv .\computers.csv |
foreach {
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $_.Computer
}

Import-Csv .\computers.csv |
foreach {
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $psitem.Computer
}

If you have the names in a text file you may be tempted to do this

Get-Content .\computers.txt |
foreach {
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName $_
}

You can also use $psitem instead of $_

A neater way is to do this

Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName (Get-Content .\computers.txt)

which gets us back to the PowerShell one liner solution.

If you’re reading the computernames from Active Directory you have to do a bit of work because the AD cmdlets don’t return a computerName property – they return name.

You can either

Get-ADComputer -Filter * |
foreach {
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3′ -ComputerName $psitem.Name
}

or if you want to be a bit cleverer

Get-ADComputer -Filter * |
select @{N=’ComputerName’; E = {$_.Name}} |
Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’

Use select-object to create a computername property on the pipeline object.

You can of course revert to the one liner solution

Get-CimInstance -ClassName Win32_LogicalDisk -Filter ‘DriveType=3’ -ComputerName (Get-ADComputer -Filter * | select -ExpandProperty name)

Use ExpandProperty on select-object to strip out the Name value and pass that to your cmdlet.

As you can see there are many ways to achieve the same goal – some easier than others. These examples aren’t necessarily complete.

Next time you need to pass a list of values to a cmdlet stop and think about the best way to do it. You might save some typing and more efficient code.


December 18, 2015  5:21 AM

WMF 5.0 now RTM

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

WMF 5.0 , including PowerShell 5.0, was released to RTM overnight – why does this lways happen when I’m asleep Smile

http://blogs.msdn.com/b/powershell/archive/2015/12/16/windows-management-framework-wmf-5-0-rtm-is-now-available.aspx

Versions are available for:

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2 SP1


December 17, 2015  1:31 PM

Outputting AD data to CSV

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Active Directory, Powershell

Back in this post https://richardspowershellblog.wordpress.com/2014/12/29/using-givenname-and-surname-instead-of-samaccountname/

I showed how to get AD information using afirst and last names rather than the samAccountName.

A question came up about reading from a CSV containing a list of names and outputting the results to another CSV.

My preference would be to create a single PowerShell pipeline.

Import-Csv -Path ./adtest.csv |
foreach  {
$fname = $psitem.GivenName
$lname = $psitem.Surname
Get-ADUser -Filter {GivenName -eq $fname -and Surname -eq $lname} -Properties * |
select SamAccountName, Division, Office, City
} |
Export-Csv aduserslist.csv –NoTypeInformation

Read the CSV and pipe to foreach. Get the data and push onto pipeline. Export to CSV.


December 15, 2015  2:33 PM

Recent Announcements from the PowerShell Team

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

The PowerShell Team have made a number of interesting  announcements recently:

Feedback is moving from Connect to User Voice

http://blogs.msdn.com/b/powershell/archive/2015/12/14/improving-the-powershell-feedback-experience-with-uservoice.aspx

This is where you give your feedback and report bugs

For programmers the PowerShell reference assemblies are now available through Nuget.org

http://blogs.msdn.com/b/powershell/archive/2015/12/12/powershell-sdk-reference-assemblies-available-via-nuget-org.aspx

Meaning you can use Install-Package to get them.  Assemblies for PowerShell versions 3.0, 4.0 and 5.0 are available

The tests the PowerShell Team uses to test new PowerShell builds are available on GitHub

http://blogs.msdn.com/b/powershell/archive/2015/12/07/powershell-tests-released-on-github.aspx

Useful to understand how PowerShell is tested and to get a deeper insight into PowerShell


December 11, 2015  6:04 AM

Formating multiple outputs

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Powershell

Using Get-WmiObject and Get-Service you can do this:

PS> Get-WmiObject -Class Win32_Service -Property StartMode -Filter “Name=’BITS’” | select StartMode

StartMode
———
Auto
PS> Get-Service -Name BITS | select Status

Status
——
Running

If you try running the two commands in a script, in ISE or even like this:

PS> Get-WmiObject -Class Win32_Service -Property StartMode -Filter “Name=’BITS’” | select StartMode; Get-Service -Name BITS | select Status

StartMode
———
Auto

You only get the first result.  If you reverse the order of the commands:

PS> Get-Service -Name BITS | select Status; Get-WmiObject -Class Win32_Service -Property StartMode -Filter “Name=’BITS’” | select StartMode

Status
——
Running

You still get the first result.

When you run a pipeline the results are automatically piped to Out-Default. The formatting system then decides to use a table format because you have less than 5 properties.

When the commands are run individually each calls Out-Default individuallly. When the 2 commands are run in a script (or other option that causes them to execuate together) the formatting takes its direction from the first object it receives and because the second object doresn’t have matching properties nothing is displayed.

The answer is to manually force each command to pipe to out-default

PS> Get-WmiObject -Class Win32_Service -Property StartMode -Filter “Name=’BITS’” | select StartMode | Out-Default; Get-Service -N
ame BITS | select Status | Out-Default

StartMode
———
Auto

 

Status
——
Running

OR

PS> Get-Service -Name BITS | select Status | Out-Default; Get-WmiObject -Class Win32_Service -Property StartMode -Filter “Name=’B
ITS’” | select StartMode | Out-Default

Status
——
Running

 

StartMode
———
Auto

This is a common issue that users trip over as they learn PowerShell.

 


December 8, 2015  11:34 AM

PowerShell Day at Manning

Richard Siddaway Richard Siddaway Profile: Richard Siddaway
Books, Powershell

Manning have a set of PowerShell books on their deal of the day for 9 December 2015. The deal includes:

Windows PowerShell in Action, Third Edition
PowerShell and WMI
PowerShell Deep Dives
Powershell in Depth, Second Edition
PowerShell in Practice
Learn Windows PowerShell in a Month of Lunches, Second Edition

The deal will go live at Midnight US ET and will stay active for ~48 hours.

Get 50% off these books with code dotd120915au at manning.com

 


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: