PowerShell for Windows Admins


May 6, 2013  9:27 AM

Scripting Games–major dislike #2

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve already blogged about incorrect use of backticks. Here is another example of un-necessary use of backticks

$Files= Get-ChildItem `
-Path $Path `
-include $Type `
-Recurse `
-File |
Where-Object {$_.LastWriteTime -lt (get-date).AddDays(-$OlderThan) }

Spreading out one parameter per line like this doesn’t add anything to the script and makes working on the get-childitem cmdlet code harder if you want to change it.

Don’t do this

May 6, 2013  7:53 AM

Scripting games-major dislike

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

One of the things we were asked to blog about as Scripting Games judges was things we liked and disliked. This code is a major dislike

Get-ChildItem $sourceDirectory | ? {$_.PsISContainer } |
% { $subDirectory = $_ ; Get-ChildItem (“$sourceDirectory\$subDirectory”) -Include *.LOG -Recurse } |
? { $logFile = $_ ; $logFile.LastWriteTime -le $modifiedCutOffDate } |
% { $logFileAndSubDirDictionary.Add($logFile, $subDirectory) }

Two things really make this stand out as how not to do things:

Using % & ? as aliases in a script. They are tolerable (just) in an interactive command but have no place in a script. Tab completion is so easy. Use the proper command.
Putting multiple commands on a line separated by ; It makes the code hard to read and awkward to work out whats going on. It also makes script testing, debug and maintenance much more difficult
Avoid these two things in your scripts


May 6, 2013  4:20 AM

Scripting Games–integer parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I keep seeing parameter constructs like this:

[int]$age = ’90′

Why set the parameter to an integer and then set the default as a string. PowerShell will convert but it just doesn’t make sense.

All you need is

[int]$age = 90


May 5, 2013  4:30 PM

Scripting games–using parameters

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I am seeing an incredible number of scripts that have this sort of coding round parameters

# Input from the user
[Parameter(Mandatory=$false,
ValueFromPipeline=$False,
Position=0)]
[ValidateScript({Test-Path $_ })]
[String]$SourcePath = ‘C:\Application\Log’,

[Parameter(Mandatory=$false,
ValueFromPipeline=$False,
Position=1)]
[ValidateScript({Test-Path $_ })]
[String]$ArchivePath = ‘\\NASServer\Archives’,

[Parameter(Mandatory=$false,
ValueFromPipeline=$False,
Position=2)]
[Int]$Days = 90

Why do you need to state that Mandatory=$false or that ValueFromPipeline=$False. The DEFAULT values are false. You only need to use them if you are setting them to TRUE.

Its a waste of coding time and processing time when you run the script.

I remember blogging about this last year.

Please stop doing it so I don’t have to blog about it next year


May 5, 2013  5:13 AM

Scripting Games–observation

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I don’t have the numbers to back this up but my feeling is that the Scripting Community is marking the entries for this years Games in a harsher manner than the judges did over the last few games.

What will be very interesting is the level, type and usefulness of the comments that come through. if you do mark low please explain why

Whether this relaxes over the next few entries will be interesting to see.


May 1, 2013  3:26 PM

Scripting Games–a word of advice for competitors

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

At the moment it isn’t necessary to run your script to give a vote.

Probably the quickest way to lose points is have an obvious and glaring error in your script such as

. . . | where {$_.LastWriteTime –lt (date).ADDdays(-90)} | . . .

or

. . . | where {$_.LastWriteTime –lt (get-date).ADDseconds(-90)} | . . .

Both of which I’ve seen today.

Please make sure your script syntax is correct before you submit otherwise all your hard work will be for nothing


May 1, 2013  2:21 PM

Filter vs Include

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

I’ve gone through most of the Beginner event submissions over the last couple of days. One thing that has jumped out is the potential misunderstanding around using the –include or –filter parameters on get-childitem.

If we look at the two parameters

-Include
Gets only the specified items. The value of this parameter qualifies the Path parameter. Enter a path element or pattern, such as “*.txt”. Wildcards are permitted.
The Include parameter is effective only when the command includes the Recurse parameter or the path leads to the contents of a directory, such as C:\Windows\*, where the wildcard character specifies the contents of the C:\Windows directory.

-Filter
Specifies a filter in the provider’s format or language. The value of this parameter qualifies the Path parameter.
The syntax of the filter, including the use of wildcards, depends on the provider. Filters are more efficient than other parameters, because the provider applies them when retrieving the objects, rather than having Windows PowerShell filter the objects after they are retrieved.

These are best explained by some examples. Lets start with the current directory

PS> Get-ChildItem -Filter *.csv | select -First 1

Directory: C:\MyData\SkyDrive\Data\scripts

Mode LastWriteTime Length Name
—- ————- —— —-
-a— 12/09/2012 19:07 2665 log.csv

but

Get-ChildItem -include *.csv | select -First 1

returns nothing

To get –Include to work you need to do this

PS> Get-ChildItem -path .\* -include *.csv | select -First 1

Directory: C:\MyData\SkyDrive\Data\scripts

Mode LastWriteTime Length Name
—- ————- —— —-
-a— 12/09/2012 19:07 2665 log.csv

The path has to be given for –Include to return anything

Looking at another folder

These work

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts -Filter *.csv

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts\* -Filter *.csv

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts\* -Include *.csv

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts -Include *.csv -Recurse

But these don’t

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts -Include *.csv

Get-ChildItem -Path C:\MyData\SkyDrive\Data\scripts\ -Include *.csv

If you want to use –Include remember the path and wildcard or use recurse


April 30, 2013  2:09 PM

Getting the folder name

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Consider the file information from get-childitem

PS> $file = ls servicesv0.6.txt

Fullname gives the full path to the file

PS> $file.Fullname
C:\MyData\SkyDrive\Data\scripts\servicesv0.6.txt

if you use DirectoryName you get the full path to the parent directory

PS> $file.DirectoryName
C:\MyData\SkyDrive\Data\scripts

The easiest way to get the folder holding the path is like this

PS> Split-Path -Path $file.DirectoryName -Leaf
scripts

However on a Windows 8/PS 3 setup you can also do this
PS> $file.Directory | select -ExpandProperty Name
scripts


April 30, 2013  1:25 PM

Don’t go mad on a one liner

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

Looking at my first group of entries for Beginners Event 1 I’ve noticed what seems like a fanatical attempt to squash everything onto one line. command; command; command; command

is NOT a one liner. The ; marks the end of a line

command | command | command | command

IS a one liner, even if it goes onto multiple lines!

Don’t think one liner – think one PIPELINE


April 30, 2013  1:19 PM

Read the Question

Richard Siddaway Richard Siddaway Profile: Richard Siddaway

When my children were at school and going off for a test or exam the last thing I told them was read the question.

It seems this needs to be repeated for the Scripting Games.  The Beginners Event 1 involved MOVING files from one server to another. I have seen a significant number of answers that are COPYING files.

Close doesn’t count in the Scripting Games.

Please read the question before diving into an answer


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: