Saturday, March 28, 2009

Free PowerShell eBooks

Just read/browsed two free PowerShell eBooks and here are my comments -

  • Frank Koch, Two books, An introduction for people with no real background knowledge and Administrative tasks. Available in German and English (only read the English version – even though I do read German). Worth a read – especially if you are new or still trying to get it. The latter covers a lot of the free add-ons you can get. The German shines through in some places in the English version, but I do not think that is too big a problem.
  • Keith Hill, Effective Windows PowerShell, 50 pages. You should read this if you have some knowledge of PowerShell. It covers the most important topics and goes quite deep into output formatters and parsing modes. Even longtime users may learn a few tricks. This books was updated March 2009 with some PowerShell v2 information.

Happy reading!

Friday, March 27, 2009

MUI for Office Communicator 2007 R2 available on TechNet

Late yesterday, the Multilingual User Interface (MUI) Pack for Office Communicator 2007 R2 was released for download on Microsoft Technet.

The following languages are included in the MUI:

Arabic
Bulgarian
Catalan
Chinese - Simplified
Chinese - Traditional
Chinese Hong Kong
Croatian
Czech
Danish
Dutch
English
Estonian
Finnish
French
German
Greek
Hebrew
Hindi
Hungarian
Italian
Japanese
Korean
Latvian
Lithuanian
Norwegian
Polish
Portuguese (Portugal)
Portuguese (Brazil)
Romanian
Russian
Serbian
Slovak
Slovenian
Spanish
Swedish
Thai
Turkish
Ukrainian

Get it here: http://www.microsoft.com/downloads/details.aspx?FamilyID=E7871DCD-8173-4866-A0C2-AF8659092ACC&displaylang=en

Thursday, March 26, 2009

Office Communications Server 2007 R2 Management Pack for System Center OpsMgr 2007 SP1

Just a quick note to let you know that the OCS 2007 R2 Management Pack for OpsMgr 2007 SP1 is now available for download.

Get it here:

http://www.microsoft.com/downloads/details.aspx?FamilyID=0FCA3752-76D4-42F3-9241-A663E40C1E2C&displaylang=en

Wednesday, March 25, 2009

Get-OpenFile

One of the many nice things about PowerShell it that you can use the existing utilities you’ve got and you love. And then you can enrich them using PowerShell. You do this best by converting the output to objects – which you then can use down the pipeline.

One such example is here. Handle.exe (sysinternals.com) returns open files (and other handles). If you wrap that with a script, you can convert the output to objects and then manipulation is so easy.

Here is Get-Openfile.ps1

param($fileFilter=$(throw "Filter must be specified"))

handle $fileFilter | foreach{
if ($_ -match '^(?<program>\S*)\s*pid: (?<pid>\d*)\s*(?<handle>[\da-z]*):\s*(?<file>(\\\\)|([a-z]:).*)') {
$matches | select @{n="Path";e={$_.file}},@{n="Handle";e={$_.handle}},@{n="Pid";e={$_.pid}},@{n="Program";e={$_.program}}
}
}





Handle must be found via $env:path or an alias. Note the use of –match and $matches and how a regex is used to match the output and easily pick up the relevant parts of the output using names. One advice: Learn regex!



An example




PS C:\Windows\PolicyDefinitions> get-openfile  er.exe

Path Handle Pid Program
---- ------ --- -------
C:\Windows\System32\en-US\... 38 7004 SearchIndexer.exe
C:\Windows\en-US\explorer.... 38 5764 explorer.exe
C:\Windows\SysWOW64\en-US\... 50 8484 explorer.exe



 



I originally called the Path property for File, but to bind the value automatically (in the pipeline), I renamed it to path.



This is nice -




PS> get-openfile  er.exe | dir

Directory: C:\Windows\System32\en-US

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 27-05-2008 09:17 7680 SearchIndexer.exe.mui

Directory: C:\Windows\en-US

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 02-11-2006 16:12 27136 explorer.exe.mui

Directory: C:\Windows\SysWOW64\en-US

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 02-11-2006 16:12 36864 explorer.exe.mui



 


 



And this is just as nice -




PS> get-openfile  er.exe | gps

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
1554 33 178276 107420 622 863,72 7004 SearchIndexer
957 87 74504 82528 356 465,01 5764 explorer
513 32 28768 34044 203 28,27 8484 explorer



 



I use the method in Get-OpenFile a lot as that provides many advantages.



 







PS. You must be administrator to run handle. Get-OpenFile simply does not return any objects if you are not an admin. Handle.exe does not set $? or $lastexitcode, so checking for the condition is not easy.



PS2. Handle.exe can also display the user name and close handles (Remove-Openfile?). It is left to the reader to implement that. Handle.exe does not display files opened across the network. –a can do that, but the path is a strange \Device\Mup path, so it is excluded.

Strange Select-Object Behavior in PowerShell V2 CTP3

In PowerShell v1, the rules are as follows -

  • Select-Object used with –first or –last do not change the object type of the objects passing through
  • Select-Object selecting properties or adding changes the object type to PSCustomObject

Proof -

PS> gps -id $pid | Get-Type # Normal
System.Diagnostics.Process
PS> gps -id $pid | select name,ws | Get-Type # PSCustomObject
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select name,ws | select | Get-Type # PSCustomObject
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select * | Get-Type # Normal (errors are left out)
System.Management.Automation.PSCustomObject
PS> gps -id $pid | select | Get-Type # Normal
System.Diagnostics.Process



 



In PowerShell V2 CTP3 the rules seem to be -




  • Select-Object used with –first or –last works as in V1


  • Select-Object, selecting properties or adding properties, creates a new type called Selected.<originaltype>


  • Select-Object resulting in a Selected.<type> will be turned into a Selected.System.Management.Automation.PSCustomObject! Very strange and very problematic in real-life use



Examples, showing it -




PS> gps -id $pid | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | Select name,ws | Get-Type # Selected.<type>
Selected.System.Diagnostics.Process
PS> gps -id $pid | Select name,ws | Select | Get-Type # Selected...PSCustomObject
Selected.System.Management.Automation.PSCustomObject
PS> gps -id $pid | select | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | select | select | Get-Type # normal
System.Diagnostics.Process
PS> gps -id $pid | select -f 1| select | Get-Type # normal
System.Diagnostics.Process
PS>



 



PS. Get-Type is not a built-in, but this function -




function Get-Type($inputObject) {
process { if ($_ -is [object]) {$_.PSTypeNames[0] } }
end { if ($inputObject -is [object]) { $inputObject.PSTypeNames[0] } }
}

PowerShell V2 CTP3 – Compatibility Problem - $MyInvocation

In PowerShell v1, you can use $MyInvocation.invocationname to test whether a script was dot-sourced or not.

This works in V1

if ($myinvocation.invocationname -ne ".") {
throw "Script should be dot-sourced to make this work"
}



but it not work in V2, and I cannot find a work-around :(




PS> '"invocation=" + $myinvocation.invocationname' | sc $env:temp\test.ps1
PS> &$env:temp\test.ps1
invocation=C:\Users\po\AppData\Local\Temp\test.ps1
PS> . $env:temp\test.ps1
invocation=C:\Users\po\AppData\Local\Temp\test.ps1
PS> # does it work when an alias is used?
PS> new-alias test $env:temp\test.ps1
PS> test
invocation=test
PS> . test
invocation=test



 



Update: Posted the problem on connect. MS has already closed my report with a 'fixed', so let's hope that is the case.

Monday, March 23, 2009

ILM “2” will ship in Q1 2010

According to my colleague, Risto Pedersen. He heard it at the keynote at TEC 2009 in Las Vegas.

Wednesday, March 18, 2009

Jeffrey Snover - Distinguished Engineer

Jeffrey, the father of PowerShell, got appointed Distinguished Engineer - well deserved. Read more here.