View all posts filed under 'Windows PowerShell'

Powershell-enabled business card :)

Friday, 25. June 2010 10:12

Hi all,

my new business cards just arrived, enjoy! Obviously, I really love Powershell ;)

Business Card

Martin

Category:Uncategorized, Windows PowerShell | Comments (2) | Author: Martin Zugec

Expand %varname%

Wednesday, 19. May 2010 12:08

Hello again! Today I will share a small PowerShell function, ExpandEnvironmentVariables that I use to expand environment variables that are written in legacy syntax (%varname%). For instance, the function is useful if you read values from configuration text files that may contain variable names.

ExpandEnvironmentVariables supports PowerShell 1 and 2. It is designed to accept pipeline input and uses the ExpandEnvironmentVariables() method of the System.Environment class to resolve variables. The function supports nested variable references

function ExpandEnvironmentVariables {
	param (
		[string]$String
	)
	begin {
		function _exp ([string]$str) {
			$s1 = $str
			$s2 = [System.Environment]::ExpandEnvironmentVariables($s1)
			while ($s2 -ne $s1) {
				$s1 = $s2
				$s2 = [System.Environment]::ExpandEnvironmentVariables($s1)
			}
			$s2
		}
	}
	process {
		if ($_) {
			$String = $_
		} elseif (!$String) {
			throw 'No value for the String parameter specified.'
		}
		_exp -str $String
	}
}

Category:Scripting, Windows PowerShell | Comment (0) | Author: Frank-Peter

Scriptbox – the Windows Script Library

Wednesday, 28. April 2010 16:51

By chance (meaning by googling something) I stumbled over a script library called Scriptbox, and I found a really useful script there. It’s a huge resource! With about 6.500 vbs, js, and ps1 scripts I consider it one of biggest libraries ever.

Category:Scripting, VBScript, Windows PowerShell | Comments (1) | Author: Frank-Peter

What Is A PowerShell Loop Label?

Wednesday, 21. April 2010 14:37

One of these days, while analyzing a PowerShell script, I noticed something strange that I didn’t see before: a so-called Loop Label.

Loop labels allow you to name a looping statement (like for, foreach, or while) and to specify that name with a continue or break statement in order to instruct PowerShell to skip the rest of the current iteration (continue) or completely halt the execution (break) of that specific loop.

When does a loop label make sense? Loop labels are only useful with nested loops meaning that if you want to halt the outer loop execution within the inner loop.

Take a look at the code below. The inner loop will be halted as soon as the inner loop counter $j has reached the value 2:

for ($i = 0; $i -lt 5; $i++) {
  for ($j = 0; $j -lt 5; $j++) {
    if ($j -eq 2) {
      break
    }
    Write-Host "outer loop counter = $i, inner loop counter = $j"
  }
}

If you want to halt execution of the outer loop instead you need to define and specify a loop label as follows:

:outerloop for ($i = 0; $i -lt 5; $i++) {
  for ($j = 0; $j -lt 5; $j++) {
    if ($j -eq 2) {
      break outerloop
    }
    Write-Host "outer loop counter = $i, inner loop counter = $j"
  }
}

Category:Scripting, Windows PowerShell | Comments (1) | Author: Frank-Peter

Default Import-Module behavior

Saturday, 10. April 2010 21:31

Ok, we all know modules in Powershell 2.0 are very cool… For me, probably the best of all newly introduced concepts is namespace support.

To make long story short – if I import function Get-Command from module SCCM, I can access it using namespace – SCCM\Get-Command.

Looks really pretty, is secured and you can use consistent function names in different modules, which is perfect from usability perspective.

You don’t need to use namespaces if you don’t want to however. So you can either use SCCM\Get-Command OR Get-Command.

Problem is that when you use Import-Module, last one always wins. So my SCCM\Get-Command still works fine, however of course it will overwrite Get-Command.

I think this is extremely dangerous behavior. If you also thing it should be changed, please vote here. My proposal is that Import-Module should get switch that will identify that all exported objects are accessible by specifying namespace also.

As a workaround, you can use following code:

Get-Command -CommandType cmdlet | ForEach-Object {Set-Alias -Name $_.Name -Value "$($_.PSSnapIn)\$($_.Name)"}

Insert this code at beginning of your script and it will take care that you won’t be able to accidentally overwrite existing cmdlets (aliases always wins).

 

Martin

Category:PowerShell, Scripting, Windows PowerShell | Comment (0) | Author: Martin Zugec

Windows PowerShell Cookbook – Next Edition

Saturday, 20. March 2010 10:51

O’Reilly has enabled Lee Holmes to publish the revised edition of Windows PowerShell Cookbook online. It is a work in progress. The content is published while it’s being written, and you can read it and submit feedback.

Category:Windows PowerShell | Comment (0) | Author: Frank-Peter

WeekOfMonth

Tuesday, 9. March 2010 19:05

Today I needed small function to determine what is the number of current week (usually referred as WeekOfMonth).

Code is very simple in fact:

Function Get-WeekOfMonth ([datetime]$Date = $(Get-Date)) {
	[int]$Day = $Date.Day
	Return [math]::Ceiling($Day / 7)
}

 

Martin

Category:General, PowerShell, Scripting, Windows PowerShell | Comment (0) | Author: Martin Zugec

Powershell coding style

Wednesday, 24. February 2010 10:41

I was reading very interesting post from Jeffrey Hicks called PowerShell Picasso today and I must say that I agree with him 99%.

If you know the way I script, then you have probably noticed that it is hybrid code between PowerShell and .NET. For example I don’t like ForEach-Object cmdlet – from my perspective, it makes code much LESS readable. I would compare it to question sentence in English and in Spanish. In Spanish, every question sentence begins with question mark (for example ¿Cómo estás?) and you immediately know it is going to be the question.

For same reason, I always use ForEach ($X in $Y) {…}. I find it much easier to undestand $X. than $_… If I have a quick peek at code, using $Service.Status immediately tells me what I need, while $_.Status requires me to read preceding code to understand what type of object is $_. Organizing code to blocks is my preferred method (while many Powershell guys organize code to sentences :) ).

Second side effect is that by using .NET syntax, people much quickly adopt the fact that Powershell is based on .NET object and is object-oriented language. Later on, these administrators can read and understand MSDN documentation or examples that are written in C#. To summarize it, my point is that for many people, Powershell can be used as entry point to .NET world (.NET for Administrators).

I fully agree with rest of the Jeffrey’s article. “Problem” as I see it is that most people use Posh in interactive mode – and there is huge difference in writing few functions for yourself and trying to build complex framework out of Powershell (just checked – my framework currently consists of almost 4000 files, even though it is based on modules). In case you don’t think about readability of your code, you will get lost when you will need to write the complex modules (thousands of lines).

Martin

Category:General, Gotcha, PowerShell, PowerShell News, Scripting, Windows PowerShell | Comment (0) | Author: Martin Zugec

What is […[]] and when should I use it?

Monday, 18. January 2010 13:27

Maybe you noticed that some Powershell scripts are using [string[]] syntax – but what does it mean?

It is pretty simple – if you add [] after your type declaration ([int[]] or [boolean[]]), it means that value is array of objects of specified type.

If you simply use [array], then it is automatically translated to [object[]]:

@(1,2,3).GetType()

And when it is useful? Usually your functions don’t accept any type of input.

When you specify array of specific type, you can let Powershell decide if it can cast to object or not.

Consider following function:

Function X ([array]$Numbers) {…}

In this case, you can use X –Numbers 1,2,3, but also X –Numbers “Martin”, “Zugec”. And you code will probably fail later on.

If you use Function X([int[]]$Numbers) {…} and try to run X – Numbers “Martin”, you will get error message:

X : Cannot process argument transformation on parameter ‘Numbers’. Cannot conve
rt value "Martin" to type "System.Int32[]". Error: "Cannot convert value "Marti
n" to type "System.Int32". Error: "Input string was not in a correct format.""

Also, sometimes you cannot use [array] – especially in case of COM classes or WMI objects. One of examples is handling Citrix policies or load evaluator rules – in that case simply use [object[]] instead of [array].

Martin

Category:Scripting, Windows PowerShell | Comment (0) | Author: Martin Zugec

Easy to use help for PowerShell

Thursday, 7. January 2010 20:14

Today, I was asked by customer if there is some reference documentation about Powershell. I told him about Get-Help (which is extremely useful), however he wanted to have something displayed next to his console prompt for easy referencing (he was using Primal documentation).

Answer is in fact very, very simple (as almost everything in Posh once you know how to do it ;) )

Simply run Get-Help with –Online switch argument and new window will open with your help in it.

 

Martin

Category:PowerShell, Scripting, Windows PowerShell | Comments (2) | Author: Martin Zugec