Categories

10501

The next Scripting Games

No – we’re not announcing the start of the next games just yet.

There is however a chance for you to shape the next games – head over to http://powershell.org/wp/2014/02/17/what-should-the-scripting-games-look-like-next-time/ and tell us what you would like to see in the next games

Countdown to the Scripting Games–32 days and counting

The countdown to the Winter 2014 Scripting Games has started.

Officially starting at 1am (UTC or GMT) 19 January 2014 the following dates should be noted:

2 January 2014 – registration opens

6 January 2014 – a practice event becomes available

19 January 2014 – event 1 starts

26 January 2014 – event 2 starts

2 February 2014 – event 3 starts

9 February 2014 – event 4 starts

 

Each event lasts one (1) week

As explained previously the events are designed to be tackled by teams of 2-6 people.

Coaching will be available during the Games if teams would like to use it.

 

The judging and coaching teams are separate.

 

Details from http://powershell.org/wp/2013/12/16/2014-winter-scripting-games-schedule/

£> (Get-Date -Day 19 -Month 1 -Year 2014 -Hour 1 -Minute 0 -Second 0 ) - (Get-Date) | Format-List Days, Hours, Minutes,
Seconds


Days      : 32
Hours     : 13
Minutes  : 47
Seconds : 33

 

Enjoy

Scripting Games countdown

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.

Winter Scripting Games scheduled

The Winter Scripting Games are tentatively schedule to start 6 January 2014 & run for 4-6 weeks depending on the number of events.

See http://powershell.org/wp/2013/09/29/winter-scripting-games-tentatively-scheduled/ for latest details

Winter Scripting Games–maybe?

Did you enjoy the Summer Scripting Games? Do you want more?

We are exploring the possibility of running a Winter Scripting Games – see http://powershell.org/wp/forums/topic/winter-games-2013/

This will be a team event (minimum of 2) that would run late this year or early next year.

Interested?

Add a comment with your thoughts on the process and the timing to the thread at the above URL

Scripting Games – what’s wrong with this

I noticed code like this in quite a few entries in for Event 1

Get-ChildItem -path C:\Application\log -Recurse -Filter *.log | Where-Object{$_.LastWriteTime -lt [DateTime]::Now.Subtract([TimeSpan]::FromDays(90))} | ForEach-Object {…}

From the title it should be obvious that there’s something I don’t like. 

The where-object re-calculates the date to test for EVERY object on the pipeline.

That’s not efficient.

Put the calculation outside your pipeline

$testdate = [DateTime]::Now.Subtract([TimeSpan]::FromDays(90))

or

$testdate = (get-date).AddDays(-90)

which I personally think is simpler

Your pipeline then becomes

Get-ChildItem -path C:\Application\log -Recurse -Filter *.log | Where-Object{$_.LastWriteTime –lt $testdate} | ForEach-Object {…}

Much simpler and more efficient.

I wonder if putting the calculation into the pipeline is part of the almost religious fervour surrounding the “one-liner”.  if you can sensibly put your code into 1 line – read one pipeline because that’s what we’re really doing – then do so. But don’t make it more inefficient as a consequence. 

Scripting Games – Filter early again

Grading the scripts in Event 4 and the one thing that jumps out is the amount of unnecessary data being carried through the scripts

You were asked for 7 properties off 20 random users

Get-ADUser has a –properties parameter. USE it to restrict the properties you return. You don’t NEED all the other properties

Next select you 20 users as soon as possible

get-aduser | get-random

will do that.  You can then format just the few properties you need on the 20 objects you have left

FILTER EARLY

Scripting Games – Win32_LogicalDisk or Win32_Volume

I have heard some discussions recently regarding whether Win32_LogicalDisk or Win32_Volume should be used in the answer to event 3 in the Scripting Games.

The problem requires you pull the drive letter, drive size and freespace for local disks on the server. Notice the emphasis – that will be important.

Looking at Win32_Volume

PS> Get-CimClass -ClassName Win32_Volume | select -ExpandProperty CimClassproperties  | select Name

Name
----
Caption
Description
InstallDate
Name
Status
Availability
ConfigManagerErrorCode
ConfigManagerUserConfig
CreationClassName
DeviceID
ErrorCleared
ErrorDescription
LastErrorCode
PNPDeviceID
PowerManagementCapabilities
PowerManagementSupported
StatusInfo
SystemCreationClassName
SystemName
Access
BlockSize
ErrorMethodology
NumberOfBlocks
Purpose
Automount
BootVolume
Capacity
Compressed
DirtyBitSet
DriveLetter
DriveType
FileSystem
FreeSpace
IndexingEnabled
Label
MaximumFileNameLength
PageFilePresent
QuotasEnabled
QuotasIncomplete
QuotasRebuilding
SerialNumber
SupportsDiskQuotas
SupportsFileBasedCompression
SystemVolume

You see 3 properties that might be of use

Get-CimInstance -ClassName Win32_Volume | select DriveLetter, Capacity, FreeSpace

is a start but I get two drives with no capacity & freespace – must by my DVD drives

I can filter those out using drive type.  DriveType =3 gives me local disks

So the WMI call I need is

Get-CimInstance -ClassName Win32_Volume -Filter "DriveType=3"  | select DriveLetter, Capacity, FreeSpace

Get-WmiObject -Class Win32_Volume -Filter "DriveType=3"  | select DriveLetter, Capacity, FreeSpace

 

Now lets look at Win32_LogicalDisk

PS> Get-CimClass -ClassName Win32_Logicaldisk | select -ExpandProperty CimClassproperties  | select Name

Name
----
Caption
Description
InstallDate
Name
Status
Availability
ConfigManagerErrorCode
ConfigManagerUserConfig
CreationClassName
DeviceID
ErrorCleared
ErrorDescription
LastErrorCode
PNPDeviceID
PowerManagementCapabilities
PowerManagementSupported
StatusInfo
SystemCreationClassName
SystemName
Access
BlockSize
ErrorMethodology
NumberOfBlocks
Purpose
FreeSpace
Size
Compressed
DriveType
FileSystem
MaximumComponentLength
MediaType
ProviderName
QuotasDisabled
QuotasIncomplete
QuotasRebuilding
SupportsDiskQuotas
SupportsFileBasedCompression
VolumeDirty
VolumeName
VolumeSerialNumber

 

I can’t find a DriveLetter but I know that DeviceId supplies that information – if in doubt check by displaying all properties of one instance or do this

PS> Get-CimInstance -ClassName Win32_Logicaldisk | ft -a

DeviceID DriveType ProviderName VolumeName      Size         FreeSpace
-------- --------- ------------ ----------      ----         ---------
C:       3                                      249951154176 146292559872
D:       3                      System Reserved 104853504    69279744
E:       2
F:       5

Drivetype matches with Win32_Volume so we get

Get-CimInstance -ClassName Win32_Logicaldisk | Select Deviceid, Size, FreeSpace
Get-WmiObject -Class Win32_Logicaldisk | Select Deviceid, Size, FreeSpace

You’ll have noticed that D: has a volume name of System Reserved. This means its a system disk that you shouldn’t be touching. Technically the event asked for information on local disks so it should be included. I know that some purists will argue against this so to remove the system volume you can

PS>  Get-CimInstance -ClassName Win32_Volume -Filter "DriveType=3 AND SystemVolume = $false"  | select DriveLetter, Capacity, FreeSpace

or

PS> Get-CimInstance -ClassName Win32_Logicaldisk -Filter "DriveType = 3 AND VolumeName <> 'System Reserved'" | select DeviceId, Size, FreeSpace

 

So either will give you the results you need.  You just need to dig into the classes a bit.

Scripting Games-Subfunctions

One of the principles of writing scripts (or any code) is the KISS principle – Keep It Simple Scripter.

That principle is being abused al lot in event 3

I am seeing numerous entries that define an advanced function as the solution and then inside the PROCESS block define one or more functions.  You PROCESS block is executed once for EVERY object on your pipeline. For 1 object might not matter but for 100s of objects it will adversely affect performance.

The solutions are such that they sensibly fit in a single solution.  If you must define additional functions make the solution a module so you only load them once.

Scripting Games–filtering on remote server

In event 3 you have to get information on hard disk capacity.  I’ve only looked at the first couple of dozen scripts but seen this too many times

Get-WmiObject -Class Win32_LogicalDisk | where DriveType -eq 3

or if you prefer the version 2 way

Get-WmiObject -Class Win32_LogicalDisk | where {$_.DriveType -eq 3}

If puppies get terminated for using Write-Host this sort of construct should triggers a mass extinction.

When pulling information back with WMI (or any other technique) from a remote server ALWAYS, ALWAYS, ALWAYS filter on the remote server.  What you are doing here is pulling back all of the data and filtering on the client. This is grossly inefficient when you are dealing with hundreds of machines.

The PowerShell team gave us the –Filter parameter on Get-WmiObject for a reason. Its to do the filtering on the remote server.

Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType = 3"

If you are guilty of not using –Filter write out 100 times “I must filter on the remote server”

And no – you can’t write a PowerShell script to do it for you!