Tuesday, July 28, 2009

How to convert [String] to [Boolean]

If you always try to specify the type (as I do), maybe you already figured out that you cannot convert string to boolean in Powershell:

[Boolean]$Var = $True
$Var = “False”


Cannot convert value "System.String" to type "System.Boolean", parameters of th

is type only accept booleans or numbers, use $true, $false, 1 or 0 instead.


At line:1 char:5


+ $Var <<<<  = "False"


    + CategoryInfo          : MetadataError: (:) [], ArgumentTransformationMet


   adataException


    + FullyQualifiedErrorId : RuntimeException



Obviously, you should use $False or 0 instead… Sometimes this can be an issue – especially if you read your configuration from XML file, it is returned as string (so it is “0” instead of 0).



There is however workaround for this that allows you to convert string to boolean:



[Boolean]$Var = $False
$Var = [System.Convert]::ToBoolean("True")


Monday, July 27, 2009

Broken New-Enum in Powershell v2

I LOVE using enums in Powershell. If you don’t know about enumerations, you should definitely learn to use them (What the heck is an ENUM?)

I will try to describe it in my words. Enums allows you to define set of allowed arguments. Consider example when I am working with a technology that considers 0 as Write, 1 as Read and 2 as ReadWrite. You will remember that while you work with it, but what if you return back to your own scripts after one year?

Normally you would write following script:

Function Set-Security ([int]$Access = 1) {…}

$Access (as you probably already knows) means which permissions you want to give and by default we set it to Read. Your code will then follow with checking if user provided correct input

Switch ($Access) {
0 {“Write”}
1 {“Read”}
2 {“ReadWrite”}
Default {“Not supported”}
}

Later on you will decide that you want to add other type (Custom) and you need to rewrite all your scripts that are using this syntax. Not talking about fact that you require from users of your scripts to use techie language and use numbers instead of words.

Instead what you can do is to create following:
New-Enum MyAccess Write Read ReadWrite (function New-Enum was taken from Powershell blog)

Now your function can be simplified:
Function Set-Security ([MyAccess]$Access) {}

You can call your function using following syntax now:
Set-Security –Access 0
Set-Security –Access “Write”
Set-Security –Access [MyAccess]::Write

If you want to extend your enumeration, you simply add new enumeration and all your functions will support it out of the box.

Using enumerations is especially useful in case you create complex scripts – for example if you export some objects to XML and import it later on. You simply specify [string]$X = [MyAccess]$Var

In your XML file, instead of non-sense numbers you will get nice string values. Import afterwards is done same way: [MyAccess]$Var = $X. I got very good experiences with this approach especially when using COM based environments like MFCOM.

Ok, so are you into enumerations? They are perfect – however they doesn’t work in Powershell v2 :( New-Enum function works correctly and doesn’t return any error, however enumerations are not created. If you run SAME New-Enum twice, then everything works as expected.

I got my slightly modified version of New-Enum that works on Posh V2 also:

function Global:S4M\New-Enum ([string] $name, [switch]$FixMode) { 

$appdomain = [System.Threading.Thread]::GetDomain()
$assembly = new-object System.Reflection.AssemblyName
$assembly.Name = "EmittedEnum"
$assemblyBuilder = $appdomain.DefineDynamicAssembly($assembly,
[System.Reflection.Emit.AssemblyBuilderAccess]::Save -bor [System.Reflection.Emit.AssemblyBuilderAccess]::Run);
$moduleBuilder = $assemblyBuilder.DefineDynamicModule("DynamicModule", "DynamicModule.mod");
$enumBuilder = $moduleBuilder.DefineEnum($name, [System.Reflection.TypeAttributes]::Public, [System.Int32]);
for($i = 0; $i -lt $Args.Length; $i++) {
If (([string]($Args[$i])).Contains("=")) {
[string]$EnumName = [string](($Args[$i].Split("="))[0])
$Null = $enumBuilder.DefineLiteral($EnumName, [int]($Args[$i].Split("="))[1]);
} Else {
$Null = $enumBuilder.DefineLiteral($Args[$i], $i);
}
}
#Used to fix issue with Powershell v2
If ($Host.Version.Major -eq 1 -or $FixMode) {
$enumBuilder.CreateType() > $Null;
} Else {
S4M\New-Enum -FixMode -Name $Name @Args
$enumBuilder.CreateType() > $Null;
}
}



This version will automatically detect which version are you running and in case you don’t run Powershell V1, it will automatically re-run New-Enum once more. Interesting is usage of @Args instead of $Args – I will blog about this next time ;)



This function contains 2 changes to original:



1.) You can assign special values to enumerations:




New-Enum MyEnum Test=1 Test2=2 Test3=256




2.) Powershell v2 compatibility is fixed

Sunday, July 26, 2009

What to expect in near future?

I was thinking about blogging in general and this blog in particular in last few days. And I made decision that I want to be more specific.

Those of you that knows me also know that I got tired by technology pretty soon – once I know it, I am looking for something else. There is however always one thing that keeps me interested – automating things ;)

So I decided that I will dedicate this blog to PowerShell – in last months I automated many technologies from XenApp through SCCM\Altiris to App-V. Every single one of them was interesting and I would like to post about using Posh V2 much more in upcoming months.

Also I would like to include all technologies related – from Subversion through different editors and tools to interesting articles.

Sunday, July 12, 2009

Adaptive smooth movie streaming

Wow, this is really nice. Jeffrey Snover posted following on Facebook.

It’s best video streaming I ever saw… Very smooth even behind proxy and try to click in the middle of video – it will almost instantly continue :)

http://www.iis.net/media/experiencesmoothstreaming

Really, really nice. Ah, and not to forget – Big Bucks Bunny is already really nice movie

Using svn:externals with TortoiseSVN and FSFS repository

 

If you use Subversion and TortoiseSVN client with repository hosted on filesystem, this can be interesting for you.

Many many years ago (4,5?) when I implemented my first repository, I used filesystem (and I still like it, simple and functional with hook scripts). Only drawback was syntax – which varied between command line subversion client and tortoise client.

In general, syntax is protocol://Location. Problem is if you are hosting your repository in UNC path. Then syntax looks really strange: file:///\server\share/repo.

Notice “\” and “/” – sometimes it works, sometimes you have to fight with it.

Recently I worked with project that was using svn:externals (you can link different repositories together, it’s like symlink on filesystem – even better, you can point to same repository, but different revision ;)). Suddenly it rejected to download externals. After a while I realized they changed syntax, you can still use old syntax, however usage of new is required in case of svn:externals (probably bug). New syntax is much easier to handle and I like it a lot.

Compare for yourself :) file:///\server\share/repo compared to file://server/share/repo.