Monthly Archives: June 2013

Need for speed?

How fast does an admin script have to be?

My opinion has always been that if its significantly faster than me doing the same task by hand then that’s more than fast enough.

Is my time better spent developing new functionality compared to shaving a few % off the execution time of my scripts? If the script is long running its either because I’m hitting a lot of data or I’m hitting a lot of machines. In both cases the script itself probably isn’t the bottle neck and if its that long an operation I can always run it over night.  A mass mailbox migration may run over a long weekend!

Speed is relative and as long the script delivers its results in an acceptable time frame the absolute time doesn’t really matter.

Using localhost

When creating functions that accept a computer name as a parameter you will often see this syntax

 

param (

[string]$computername = ‘localhost’

)

This is designed to give a default value in the event of a value not being passed.  That’s a good idea if there is a sensible, safe, value you can use and you aren’t making the parameter mandatory.

The only objection I have is to using ‘localhost’

I have seen this break down  - for instance if you try to use the System.DirectoryServices.AccountManagement classes against accounts on the local machine. On the other hand you have to use it when dealing with the WSMAN provider.

Just be aware that ‘localhost’ can cause issues

Refreshing values

The CIM cmdlets in PowerShell v3 enable you to refresh the data in the object.  Try this:

$p = Get-CimInstance -ClassName Win32_PerfFormattedData_PerfOS_Processor
$p | Get-CimInstance | select percentprocessortime

  $p will remain unchanged.  Another use for this is monitoring processes – you could check on CPU utilisation

PowerShell presentations

Jeffrey Snover and Jason Helmick will be presenting by webcast 18 July 9am – 5pm (PDT) on “Getting started with PowerShell”

Details from http://powershell.org/wp/2013/06/27/a-special-presentation-on-getting-started-with-powershell/

A follow up day of presentations will occur in August delving further into scripting, automation and building tools

Writable properties for a WMI class

Do you know how to discover which properties on a WMI class, and therefore a WMI instance, can be modified?

Get-CimClass from the PowerShell 3.0 CIM cmdlets is the answer:

$class = Get-CimClass -ClassName win32_volume

$class.CimClassProperties

 

The last command returns all of the properties in this format

 

Name               : Description
Value              :
CimType            : String
Flags              : Property, ReadOnly, NullValue
Qualifiers         : {read}
ReferenceClassName :

 

Name               : DriveLetter
Value              :
CimType            : String
Flags              : Property, NullValue
Qualifiers         : {read, write}
ReferenceClassName :

 

Notice the first one has a Flag of ReadOnly and the second one has a Qualifier of write. So the question becomes how can you filter on those two items?

 

If you run something like this:

$class = Get-CimClass -ClassName Win32_Volume
$class.CimClassProperties |
foreach {
if ($psitem | select -ExpandProperty Qualifiers | where Name -eq 'write'){$psitem}
if (($psitem.Flags -split ', ') -notcontains 'Readonly')  {$psitem}
}

 

You will see that some properties may not be Readonly but also aren’t writable such as:

Name               : NumberOfBlocks
Value              :
CimType            : UInt64
Flags              : Property, NullValue
Qualifiers         : {MappingStrings}
ReferenceClassName :

 

In that case we need just the writable properties

Get-CimClass -ClassName Win32_Volume  |
select -ExpandProperty CimClassProperties |
foreach {
if ($psitem | select -ExpandProperty Qualifiers | where Name -eq 'write'){$psitem}
}

 

This brings the results down to three properties DriveLetter,  IndexingEnabled,  Label

The first and last I expected – IndexEnabled was new to me

Automation tools?

In this post http://richardspowershellblog.wordpress.com/2013/06/23/opinionautomate-or-suffer/ I talked about the need for admins to learn to automate. A couple of comments brought up the need for tools to create our automation scripts.

I remember the 4th generation languages of the late 1980s & 1990s.  The promised that you wouldn't have to code – just drag & drop onto the designer, answer a few questions and your application was created.

The worked great – as long as you wanted a cookie cutter application that only had limited functionality and was dog slow.

Automating code generation, in my experience, is a hard task. Compare the PowerShell snippets that come out of AD Admin center or the Exchange Management Console with what you actually write. They are usually very verbose and include lots of stuff you don’t need.

If someone can create a tool that creates my code for me, with minimal input on my side then I’ll sign up for it. I suspect it’ll be a long time coming. Until then happy coding.

Windows Management Framework 4.0 preview

The PowerShell 4.0 preview is now available.  It comes as part of WMF 4.0

 

Windows Management Framework 4.0 Preview includes updates to Windows PowerShell, Windows PowerShell ISE, Windows PowerShell Web Services (Management OData IIS Extension), Windows Remote Management (WinRM), Windows Management Infrastructure (WMI), the Server Manager WMI provider, and a new feature for 4.0, Windows PowerShell Desired State Configuration (DSC).

 

Download is available at

http://www.microsoft.com/en-us/download/details.aspx?id=39347

Note: It only installs on these versions of Windows

  • Windows 7 with Service Pack 1
  • Windows Server 2008 R2 with Service Pack 1
  • Windows Server 2012

Windows 8 is not an option

Dropping a database

A question came up on the forum regarding dropping a database & I realised it was something I hadn’t done before.

SMO provides a set of classes for managing SQL Server. You get SMO when you install the SQL Server management tools

Import the module to load SMO assemblies

import-module sqlps

get the server object and view the databases
$server = New-Object  Microsoft.SqlServer.Management.Smo.Server("w12scorc")
$server.Databases

view the target database
$server.databases["mydb"]

drop the database and view the databases again
$server.databases["mydb"].Drop()
$server.databases

RDP annoyance

I’ve RDPing into a number of servers from different systems recently and the way the screen resolution changes to match your monitor size is annoying. If I use the shortcut to the session I get whatever sizes were set in the last session so often logon, curse when the size isn’t convenient and logoff and reset.

maybe I should just buy a giant monitor?

Windows Server 2012 R2

The Windows Server 2012 R2 preview is available on MSDN subscriber downloads. It has PowerShell v4!!!!