Categories

Monthly Archives: May 2011

PowerShell Basics: 3 When not to use PowerShell

Is there a time when you shouldn’t use PowerShell – No

Is there a time when there might be better alternatives – Yes

I can think of a number of situations where writing a PowerShell script may not be the most effective answer:

  • a simple one off or very infrequent task that can be done in the GUI
  • you have a VBScript that works – convert it to PowerShell when it needs updating not now
  • there is a command line utility that can do the job that you know how to use
  • you need maximum performance – means you need compiled code

There will be more that you can think of but these cover the main scenarios I’ve seen.

Spend your PowerShell time being productive and automate the most common and/or repetitive tasks first. You’ll soon save the time to tackle the more difficult, complex or infrequent tasks

PowerShell Basics: 2 Utility cmdlets

 

The utility cmdlets are the glue that we use to bind our actions together on the PowerShell pipeline. We can easily discover the list of utility cmdlets by using

Get-Command *-object

I split the utility cmdlets into two groups.  The first group I use all of the time

ForEach-Object
Select-Object
Sort-Object
Where-Object

The second group provides functionality that I don’t use as much but saves me a ton of time when I need it

Compare-Object
Group-Object
Measure-Object
New-Object
Tee-Object

PowerShell’s verb-noun naming convention for cmdlets should be sufficient to figure out what each of them does.  Check out the help file for these cmdlets.  Another good reference is the web cast I did a few months back

Details from here http://msmvps.com/blogs/richardsiddaway/archive/2011/02/08/tonight-s-slides-and-recording.aspx

Advanced Function Template typo

Just discovered a typo in the advanced function template I posted.

http://msmvps.com/blogs/richardsiddaway/archive/2011/05/24/advanced-function-template.aspx

It should be

function aaaa-yyyyyy{
[CmdletBinding(SupportsShouldProcess=$true,
    ConfirmImpact="Medium Low High None",
    DefaultParameterSetName="XXXXX")]
param (
[parameter(Position=0,
   Mandatory=$true,
   ParameterSetName="YYYYYYYYYY",
   ValueFromPipeline=$true,
   ValueFromPipelineByPropertyName=$true,
   ValueFromRemainingArguments=$true,
   HelpMessage="Put your message here" )]
   [Alias("CN", "ComputerName")] 
   [AllowNull()]
   [AllowEmptyString()]
   [AllowEmptyCollection()]
   [ValidateCount(1,10)]
   [ValidateLength(1,10)]
   [ValidatePattern("[A-Z]{2,8}[0-9][0-9]")]
   [ValidateRange(0,10)]
   [ValidateScript({$_ -ge (get-date)})]
   [ValidateSet("Low", "Average", "High")]
   [ValidateNotNull()]
   [ValidateNotNullOrEmpty()]
   [string]$computer="."
)
BEGIN{}#begin
PROCESS{

if ($psCmdlet.ShouldProcess("## object ##", "## message ##")) {
    ## action goes here
}

}#process
END{}#end

<#
.SYNOPSIS


.DESCRIPTION


.PARAMETER  <Parameter-Name>


.EXAMPLE


.INPUTS


.OUTPUTS


.NOTES


.LINK

#>

}

 

The difference is in the Alias parameter.  It should be stand alone NOT included as part of the Parameter arguments.

PowerShell UG–June 2011 reminder

Don’t forget to add the June meeting of the UK PowerShell User group to your calendar.  Its June 21 at 7.30pm BST. Details available from

http://msmvps.com/blogs/richardsiddaway/archive/2011/05/10/powershell-uk-user-group-june-meeting.aspx

Hardware Update

Last year I bought a Lenovo W510 to use as my mobile(ish) Hyper-V lab.  I mentioned the initial problems I’d had with core parking - http://msmvps.com/blogs/richardsiddaway/archive/2010/08/06/lenovo-w510-hyper-v-and-bsod.aspx

Once those were resolved I haven’t had any other problems with it.  I never did get Virtual Machine Manager installed – I tripped over a problem that VMM won’t recognise the agent. Other people have reported the same problem (with different hardware and configurations so its not a W510 issue) but there doesn’t seem to be a known fix.  I might try again with VMM some day but at the moment I can live without.

All in all very satisfied with the W510 – it does what I required and gives me sufficient performance for  experimentation and demos.

Last years other purchase was a HP Mini netbook

http://msmvps.com/blogs/richardsiddaway/archive/2010/07/11/netbook-revisited.aspx

This has been even better.  Its my travelling machine of choice. I can work with Office documents, browse Internet, use my e-readers and even write PowerShell scripts.  I’ve run a number of presentations off it and it works excellently.

Another winner.

Next purchase is likely to be a tablet of some kind. Maybe this year or maybe wait until next version of Windows and see what comes along then

PowerShell Basics: 1 What is PowerShell?

Discussions at the PowerShell Deep Dive and the entries for the Scripting Games showed me that there is tremendous amount of interest in PowerShell but that there are a lot of people that are still unsure of how to get started on want to take PowerShell a bit further than stringing cmdlets together on the command line.

Don’t misunderstand me – the interactive use of PowerShell on the command line is one of its greatest strengths and something I use practically every day. In this series of posts I want to look at first steps in using the PowerShell language. We’ll cover using the pipeline as we go.

I’ve been asked many times what is Powershell and I’ve heard many answers to the question:

  • Interactive and interpreted .NET language
  • .NET at the command line
  • Scripting language
  • Command line admin tool
  • Command line admin tool for AD, Exchange, <insert your technology here>
  • Replacement for cmd.exe
  • Replacement for VBScript
  • etc
  • etc

My answer is that PowerShell is Microsoft’s Automation Engine. The greatest feature is that it can be used interactively and in scripts and you will get the same results. This means you can experiment at the command line, get everything working and then move it straight into a script. The opposite is true – you can run a script so that variables are kept in memory and then experiment to get round a difficult problem.

PowerShell can be thought of as two sets of functionality:

  • cmdlets that supply a way to do something
  • a language that wraps round the cmdlets to help manipulate the results.

In some cases the two can overlap  for instance if you came from a traditional scripting background you might do something like this

001
002
003
004
005
006

$processes = Get-Process 
foreach ($process in $processes
){
 
if ($process.Handles -gt 500
){
  
Write-Output $process
 }
}

 

Use the Get-Process to get a list of processes; test each process to see it uses more than 500 handles and if it does write out the process information.

At this point anyone who has used PowerShell will be shouting “use the pipeline”

We can get exactly the same results like this

Get-Process | Where-object {$_.Handles -gt 500}

 

We pipe the Get-Process results into Where-Object which filters out those processes with more than 500 handles.  We can then take it a stage further and sort the results

Get-Process | Where-object {$_.Handles -gt 500} | sort-object Handles –Descending

 

Adding a sort to our first way of doing things would be more difficult.

 

The first thing to remember about PowerShell is Get the pipeline to do the work for you. The PowerShell team have done an excellent job of supplying utility cmdlets such as sort that can save masses of time and effort compared to trying to write your own.

Next time we’ll look at the utility cmdlets in more depth.

Manning Deal of the Day–29 May

Today, for one day only, get 50% off PowerShell and WMI MEAP or MEAP+ebook.

 

The code is dotd0529cc when you order from www.manning.com

 

The same code can be used for PowerShell in Action – second edition and PowerShell in Practice

root\wmi–MSBatteryClass

A number of the classes in root\wmi return results from more than one class. That sounds odd but it can be explained by an example.

The namespace contains a number of classes related to the battery in laptops

gwmi -Namespace root\wmi -List *battery*

MSBatteryClassEvent
BatteryStatusChange
BatteryTagChange
MSBatteryClass
BatteryStaticData
BatteryRuntime
BatteryCycleCount
BatteryTemperature
BatteryStatus
BatteryFullChargedCapacity

 

We’ll ignore the event and change classes for now.  If we pick out the MSBattery class we get information from a number of other classes returned – MSBattery is a super class.

PS> gwmi -Namespace root\wmi -Class MSBatteryClass | select __class

__CLASS
-------
BatteryCycleCount
BatteryFullChargedCapacity
BatteryStaticData
BatteryRuntime
BatteryStatus

 

Be aware that the runtime property returned by BatteryRuntime doesn’t respond to calculations you may find on the Internet when your OS is Windows 7

Battery status is a useful class to determine if you are on battery or external power & if the battery is charging

root\wmi – speeding the testing

Testing the individual classes in root\wmi is a pain – so its time for some brute force.  I’ll select a group of classes and test the selection

gwmi -Namespace root\wmi -List system* | fw

 

I can then iterate through them calling get-wmiobject.

This is a command line activity so aliases are OK

gwmi -Namespace root\wmi -List system* | foreach {gwmi -Namespace root\wmi -Class $_.Name}

 

I could do this for all classes but it could become a bit difficult sorting out results if I get a lot of them.  We’ll see where this goes.

root\wmi – MS_SystemInformation

Continuing our exploration of the murky jungle that is the root\wmi namespace we find a number of classes related to system configuration

gwmi -Namespace root\wmi -List *system* | fw

 

Of theses the only one I could get a respnse from on Windows 7 or Windows 2008 R2 was MS_SystemInfo.

gwmi -Namespace root\wmi -Class MS_SystemInformation

Active                 : True
BaseBoardManufacturer  : Wistron
BaseBoardProduct       : 303C
BaseBoardVersion       : 08.48
BiosMajorRelease       : 15
BiosMinorRelease       : 52
BIOSReleaseDate        : 12/23/2008
BIOSVendor             : Hewlett-Packard
BIOSVersion            : F.34
ECFirmwareMajorRelease : 255
ECFirmwareMinorRelease : 255
InstanceName           : Root\mssmbios000_0
SystemFamily           : 103C_5335KV
SystemManufacturer     : Hewlett-Packard
SystemProductName      : HP G60 Notebook PC
SystemSKU              : NF300EA#ABU
SystemVersion          : F.34

 

It seems to combine some information from

Win32_ComputerSystem

Win32_BaseBoard

Win32_Bios