PowerShell for Windows Admins


July 30, 2013  2:04 PM

Is PowerShell too big?

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I was thinking the other day about the differences between PowerShell v1 and the new v4 we’ll be getting soon. There is so much in PowerShell that its very difficult to be an expert in aspects.

Think about these topics for a moment:

PowerShell pipeline
Error handling and debugging
Objects
Scope
Formatting
Extensible type System
PowerShell remoting
PowerShell jobs
Advanced functions
Modules
Splatting
CIM sessions
CDXML
Workflows
Scheduled jobs
Internationalization
Desired State Configuration
And all of that is before you start adding in the cmdlets for administering specific parts of your environment – AD, Exchange, SQL Server, SharePoint, DNS, DHCP, networks, backup etc etc etc.

PowerShell has got to the point where you can’t expect to be an expert in every facet. Have a working knowledge of as much as possible but specialise where it will help you do your job.

That’s why it took three of us to write PowerShell in Depth!

July 30, 2013  12:42 PM

off with his head

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

CSV files are great for passing information around and are very easy to use in your PowerShell scripts. Sometimes, your CSV may have a problem – for instance it doesn’t have a header row. At that point the data becomes a bit difficult to use:

£ Import-Csv .\htest.csv | Format-Table -AutoSize

2 Red 23.8 47.6
- — —- —-
7 Blue 24.0 168.0
15 Green 2.5 37.5

Luckily there is an answer. Create your own headers:

£ Import-Csv .\htest.csv -Header “Number”, “Colour”, “Price”, “Total” | Format-Table -AutoSize

Number Colour Price Total
—— —— —– —–
2 Red 23.8 47.6
7 Blue 24.0 168.0
15 Green 2.5 37.5

Makes much more sense now.

You can also override existing headers

£ Import-Csv .\htest.csv -Header “Number”, “Colour”, “Price”, “Total” |
>> select -Skip 1 | Format-Table -AutoSize
>>

Number Colour Price Total
—— —— —– —–
2 Red 23.8 47.6
7 Blue 24.0 168.0
15 Green 2.5 37.5

The select call is used to skip the old header row.

If you run queries in SQL Studio Management Studio and export the results to a CSV file you will get a file without headers. This technique comes in useful at that point.


July 21, 2013  12:10 PM

PowerShell remoting book

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I mentioned several times during the Q&A for the PowerShell jump start that a free PowerShell remoting book was available from powershell.org

The book can be found here – http://powershell.org/wp/books/

Scroll down the list to see lots of free books


July 21, 2013  9:48 AM

Fun with prompts

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

At the PowerShell Jumpstart event there were a lot questions asking how Jeffrey Snover managed to get a dollar sign – $ – as his prompt. A lot of them centred on asking if this was a PowerShell v4 thing.

Its not a V4 thing. You have been able to change the prompt since v1.

The PowerShell prompt is by default the path of your current folder. This can easily take half the width if the screen if if you are several layers deep

You can change the PowerShell prompt by running a prompt function. For instance to change the prompt to a dollar sign

PS C:\Windows\system32> function prompt {
>> “$ ”
>> }
>>
$

I move the folder information into the header

$ function prompt {
>> “$ ”
>> $host.ui.RawUI.WindowTitle = $(get-location)
>> }
>>

Other useful tricks – are you running 32 bit or 64 bit PowerShell? Its easy to forget if you have numerous consoles open.

PS>function prompt {
>> if ([System.IntPtr]::Size -eq 8) {$size = ’64 bit’}
>> else {$size = ’32 bit’}
>> $host.ui.RawUI.WindowTitle = “$size $(get-location)”
>> “$ ”
>> }
>>
$

This adds 64 bit or 32 bit to the console header. As well as the location.

One final option is to show if you are running that console elevated or not.

function prompt {
if ([System.IntPtr]::Size -eq 8) {$size = ’64 bit’}
else {$size = ’32 bit’}

$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$secprin = New-Object Security.Principal.WindowsPrincipal $currentUser
if ($secprin.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator))
{$admin = ‘Administrator’}
else {$admin = ‘non-Administrator’}

$host.ui.RawUI.WindowTitle = “$admin $size $(get-location)”
“$ ”
}

The Windows identity of the current user is retrieved and used to create a security principal object. This is used to test is the security principal is in the Administrator role.

Add this prompt function to your profile and you get some useful reminders for while you are working and a minimalist prompt.


July 21, 2013  9:03 AM

PowerShell Deep Dives is published

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell Deep Dives is a collection of chapters from PowerShell authorities world wide. The book is now published http://manning.com/hicks/

The royalties from the book all go to Save the Children

If you’ve bought a copy thank you for your support – your book will be with you soon. If you haven’t got a copy please buy one. You will be supporting a very good cause and getting your hands on PowerShell material you won’t find elsewhere.


July 17, 2013  2:05 PM

Internet Connection

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Can you find the network adapter on your machine that’s connected to the Internet? On a Windows 8/2012 machine its fairly simple:

PS> Get-NetConnectionProfile -IPv4Connectivity Internet

Name : NetworkName
InterfaceAlias : AdapterName
InterfaceIndex : 12
NetworkCategory : Private
IPv4Connectivity : Internet
IPv6Connectivity : LocalNetwork

What else can you discover?

The important information is the InterfaceIndex

Get-NetAdapter -InterfaceIndex 12

shows the NIC information such as name, MAC address and speed (similar to Win32_NetworkAdapter)

Get-NetAdapterAdvancedProperty -Name name

shows buffer data

Get-NetAdapterStatistics -Name name

shows transmitted data

Get-NetIPConfiguration -InterfaceIndex 12

pulls the IP configuration

This just scratches the surface to the networking modules in Windows 8/2012

The modules are based on new WMI classes for the most part so you won’t find them on legacy operating systems even with WMF 3 loaded.


July 16, 2013  12:51 PM

CSV fields with spaces in the field name

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

CSV files are one way we can get data into our scripts – but sometimes when we get given a CSV file it has spaces in the field name e.g.

“Area Number”
1
2
3
2
3
1
5

Dealing with this can be a bit awkward but you can access the field like this:

Import-Csv area.csv |
foreach {
$_.’Area Number’
}

Double quotes work as well

The trick comes if you need to add the field into a string

Import-Csv area.csv |
foreach {
“Area = ” + $_.’Area Number’ + ” is available”
}

String concatenation works. Alternatively, if you want to use string substitution:

Import-Csv area.csv |
foreach {
“Area = $($_.’Area Number’) is available”
}


July 15, 2013  12:32 PM

AD Management MEAP

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

A new MEAP was released last week for AD Management in a Month of Lunches. Chapters 1-15 are now available

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


July 8, 2013  3:31 PM

Case sensitive operators

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell is more or less case insensitive so the operation in my previous post

$_.Substring(3,1) -ne “T”

will trigger on “T” or “t”
If you only want the uppercase version to fail then you can use the case sensitive version of –ne which is –cne.
This changes the script to:

function ptest {
[CmdletBinding()]
param(
[ValidateScript({$_.Substring(3,1) -cne "T" })]
[string]$server
)
Write-Host “$server”
}

You can read more about the comparison operators in
get-help about_Comparison_Operators


July 8, 2013  1:39 PM

Validating parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

PowerShell provides a number of ways of validating the values input to the parameters in your scripts. One such way is Validate script. I came across an interesting question where the inquirer wanted to test an input parameter and throw an error if the 4th character was a “T”

One solution is:

function ptest {
[CmdletBinding()]
param(
[ValidateScript({$_.Substring(3,1) -ne "T" })]
[string]$server
)
Write-Host “$server”
}

Alternatively use a regular expression


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: