Keith's profileKeith Hill's BlogPhotosBlogListsMore Tools Help

Keith Hill's Blog

Windows PowerShell MVP / P.S. I'M A PC AND I'm Running Windows Vista and Windows 7
May 22

PSCX Tips Part 2

This is a continuation of PSCX Tips Part 1.  Here are some more things you can do with the PowerShell Community Extensions.

If you do .NET software development and partially strong name your assemblies then you know that at some point in your official build process you need to finish the strong-naming process.  When we have done this, we cycle through all the exes and dlls in a common output dir and apply the full strong name.  Problem is that we have some native binaries mixed in with the managed binaries.  So we need some quick way to test if a file is a managed assembly.  This is where Test-Assembly comes in handy:

PS> Get-ChildItem | Where {$_ –match '\.(dll|exe)$' –and (Test-Assembly $_)} |
    Foreach {sn.exe /Ra $_.fullname $pathToKeyFile}

On 64-bit Windows you may want to know whether a binary is a 32-bit or 64-bit binary.  That’s easy with Get-PEHeader:

PS> Get-PEHeader .\wordpad.exe

Type                    : PE64
LinkerVersion           : 9.0
OperatingSystemVersion  : 6.1
ImageVersion            : 6.1
SubsystemVersion        : 6.1
SizeOfCode              : 604672
SizeOfInitializedData   : 3915776
SizeOfUninitializedData : 0
AddressOfEntryPoint     : 65624
BaseOfCode              : 4096
BaseOfData              : 0
ImageBase               : 4294967296
SectionAlignment        : 4096
FileAlignment           : 512
Win32VersionValue       : 0
SizeOfImage             : 4538368
SizeOfHeaders           : 1536
Checksum                : 4583061
Subsystem               : Windows
DllCharacteristics      : 33088
SizeOfStackReserve      : 524288
SizeOfStackCommit       : 8192
SizeOfHeapReserve       : 1048576
SizeOfHeapCommit        : 4096
LoaderFlags             : 0

Need to test if the current user is elevated on Vista or Windows 7?  Use Test-UserGroupMembership e.g.:

PS> Test-UserGroupMembership -GroupName Administrators
False

Need to know what the 8.3 filename is for a file?  Use Get-ShortPath e.g.:

PS> Get-ShortPath '.\Windows Azure SDK'
C:\PROGRA~1\WI4C87~1

Need a touch like utility to change a file’s various time fields?  Try Set-FileTime e.g.:

PS> Set-FileTime .\test.csv -Modified (Get-Date).AddDays(-2)

Need to compute the hash for a string or an entire file using various algorithms e.g.:

PS> "hello world" | Get-Hash

Algorithm: MD5

Path       :
HashString : E42B054623B3799CB71F0883900F2764

PS> Get-Hash .\uszip.wsdl -Algorithm SHA1

Algorithm: SHA1

Path       : C:\Users\Keith\uszip.wsdl
HashString : 74910AE77B4089496D5EF829DF3F0485BF855EB9

Need to convert between different OS style line endings in files?  Check out these cmdlets;

  • ConvertTo-MacOs9LineEnding
  • ConvertTo-UnixLineEnding
  • ConvertTo-WindowsLineEnding

Need to convert from or to Base64?  Try out the ConvertTo-Base64 and ConvertFrom-Base64 cmdlets e.g.:

PS> [byte[]](1..255) | ConvertTo-Base64
AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5
Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFy
c3R1dnd4eXp7fH1+f4CBgoOEhYaHiImKi4yNjo+QkZKTlJWWl5iZmpucnZ6foKGio6Slpqeoqaqr
rK2ur7CxsrO0tba3uLm6u7y9vr/AwcLDxMXGx8jJysvMzc7P0NHS09TV1tfY2drb3N3e3+Dh4uPk
5ebn6Onq6+zt7u/w8fLz9PX29/j5+vv8/f7/

When parsing legacy exe text, do you ever need to skip either the first couple of lines or perhaps the last line (or both)?

Skip-Object is very convenient here because you don’t need to know the length of the sequence you are dealing with.  Here’s an example:

PS> 1..10 | Skip-Object -First 2 -Last 1 -Index 4,6
3
4
6
8
9

That’s enough for this post but there’s still plenty more in PSCX.  Stay tuned.

May 20

PSCX Tips

We recently released a beta of the PowerShell Community Extensions that supports PowerShell V2 in addition to V1.   This version also supports 64-bit versions of Windows.  The primary purpose of PSCX is to flesh out the functionality of PowerShell such that tools like cygwin and MKS Toolkit aren’t needed.  We aren’t completely there with PSCX yet but there is quite a bit of useful functionality in PSCX.  Here are some examples.

Enhanced CD function has browser like backwards and forwards history:

PS> cd $pshome;cd $pscx:home;cd $pscx:ScriptsDir;cd~
C:\Windows\System32\WindowsPowerShell\v1.0
C:\Users\Keith\Pscx\Trunk\Src\PscxSnapin\bin\Debug
C:\Users\Keith\Pscx\Trunk\Src\PscxSnapin\bin\Debug\Scripts
C:\Users\Keith

PS> cd

     # Directory Stack:
   --- ----------------
     0 C:\Users\Keith
     1 C:\Windows\System32\WindowsPowerShell\v1.0
     2 C:\Users\Keith\Pscx\Trunk\Src\PscxSnapin\bin\Debug
     3 C:\Users\Keith\Pscx\Trunk\Src\PscxSnapin\bin\Debug\Scripts
->   4 C:\Users\Keith

# Use cd - and cd + to move backwards and forwards through stack
PS> cd -
C:\Users\Keith\Pscx\Trunk\Src\PscxSnapin\bin\Debug\Scripts

PS> cd +
C:\Users\Keith

# Or specify an entry number to jump to directly
PS> cd –1
C:\Windows\System32\WindowsPowerShell\v1.0

# cd up several dir levels at once
PS> cd ....

Sending PowerShell output to the clipboard:

PS> Get-Process | Out-Clipboard

# The following uses the alias ocb and sets output width to prevent text truncation
PS> Get-ChildItem env: | ocb –width 9999

# To get the raw data without any PowerShell formatting
PS> $pwd | Write-Clipboard
 

Inspecting the contents of a file ala od.exe  (octal dump):

# View the first 16 bytes of powershell.exe
PS> Format-Hex $pshome\powershell.exe –count 16

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ASCII
-------- ----------------------------------------------- ----------------
00000000 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ..............

# Using the fhex alias to inspect a text file to see if it has the UTF-8 BOM
PS>
fhex $pshome\FileSystem.format.ps1xml -count 48

Address:  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F ASCII
-------- ----------------------------------------------- ----------------
00000000 EF BB BF 3C 3F 78 6D 6C 20 76 65 72 73 69 6F 6E ...<?xml version
00000010 3D 22 31 2E 30 22 20 65 6E 63 6F 64 69 6E 67 3D ="1.0" encoding=
00000020 22 75 74 66 2D 38 22 20 3F 3E 20 0D 0A 3C 21 2D "utf-8" ?> ..<!-

Formatting XML:

# Ever have an XML string display as one long line, try this out
PS> "<a><b><c><d/></c></b></a>" | Format-Xml # Alias is fxml
<a>
  <b>
    <c>
      <d />
    </c>
  </b>
</a>

Testing XML for well-formedness and against a schema:

PS> "<a><b><c><d/></c></b></a>" | Test-Xml
True
PS> "<a><b><c><d/><c></b></a>" | Test-Xml -verbose
VERBOSE: The 'c' start tag on line 1 does not match the end tag of 'b'. Line 1, position 19.
False

PS> $schemaPaths
C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\1033\Microsoft.Build.xsd
C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\1033\MSBuild\Microsoft.Build.Core.xsd
C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\1033\MSBuild\Microsoft.Build.CommonTypes.xsd

PS> Test-Xml .\ConsoleApplication1.csproj -SchemaPath $schemaPaths
True

Applying a XSL transform to a file:

PS> Convert-Xml My.xml –XsltPath My.xsl –EnableScript

There is a lot more functionality in PSCX such as the ability to create, read and expand ZIP and TAR files.  But that is enough of a teaser for this post.  Stay tuned for more info on what’s in PSCX.

May 14

PSCX 1.2 Beta Available

Last night we released a beta of the PowerShell Community Extensions 1.2.  The release supports Windows PowerShell V2 and has better support for 64-bit Windows.  PowerShell MVP/Rockstar Oisin Grehan has added two very useful cmdlets to this release: Read-Archive and Expand-Archive which works not only on TAR and ZIP files but also on ISO files.  Give it a spin.  You can download it here.  Be sure to let us know if you run into any problems either via the PSCX discussion forum or issue tracker.  BTW, there are two known issues on x64 Windows.  The cmdlets Get-PEHeader and Test-Assembly don’t work.  After a week or so, we’ll look at officially releasing 1.2.

May 02

PowerShell V2 Remoting on Workgroup Joined Computers – YES It Can Be Done

There are a number of extra steps to take to V2 remoting to work on workgroup joined computers like the ones in your home – unless you’re running a DC at home (sick puppy).  First up, is a registry setting that makes V2 remoting work on workgroup computers:

PS> new-itemproperty -path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System -name LocalAccountTokenFilterPolicy -propertyType DWord -value 1

Be sure to run this from an elevated prompt.  Then from that same elevated prompt, execute the following cmdlet:

PS> Set-WSManQuickConfig –force

To verify that remoting is working on this PC by executing the following command (also from an elevated prompt):

PS> Enter-PSSession localhost

If remoting is working you should get a prompt something like this:

[localhost]: PS C:\Users\Keith\Documents>

Finally, on the PC(s) that you want to use to initiate remoting, execute this command so that all the local target computers are trusted:

PS> set-item wsman:localhost\client\trustedhosts -value *

Now, at this point you should be able to enter a new pssession to a remote computer.  Note that you don’t have to be in an elevated prompt to do this.  However you will need to pass your credentials to the remote computer like so:

PS> $cred = Get-Credential  # Type in the username/password for an admin account on the remote PC
PS> Enter-PSSession MediaCenterPC –cred $cred

Credential Delegation

One other area that can bite you is credential delegation.  Here is the scenario.  Say you remote into a PC and from that PC you want to access files on another PC via a UNC share.  As things stand now, you run into the following error:

[mediacenterpc]: PS C:\Users\Keith\Documents> dir \\homeserver\photos
Get-ChildItem : Cannot find path '\\homeserver\photos' because it does not exist.
    + CategoryInfo          : ObjectNotFound: (\\homeserver\photos:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

To fix this you have to enable credential delegation (second hop) and use CredSSP authentication.  First on the target/remote computer you need to run this in an elevated prompt:  Note that you can’t run this from a V2 remoting session (you’ll get “access is denied”):

PS> Enable-WSManCredSSP –Role Server

Now on your client/local computer execute the following from an elevated prompt for each remote computer you need credential delegation for:

PS> Enable-WSManCredSSP –Role Client –DelegateComputer <computer_name>

We are close but there is one last step and it requires a tweak via the global policy editor.  Run gpedit.msc and navigate to Computer Configuration –> Administrative Templates –> System –> Credential Delegation as shown below:

image

Open up the “Allow Delegating Fresh Credentials with NTLM-only Server Authentication” setting.  Enable the setting and then click on the “Show…” button to add a server to the list.  I added mine like so:

image

Press OK and then press the “Apply” button on the previous dialog to apply the setting.  Now credential delegation will work for that configured remote computer.  Note that when you enter a new PSSession you have to use CredSSP authentication as shown below:

PS> Enter-PSSession MediaCenterPC -Cred $cred -Authentication CredSSP
[mediacenterpc]: PS C:\Users\Keith\Documents> dir \\HomeServer\Software

    Directory: \\HomeServer\Software

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----         7/21/2008   9:37 PM            Add-Ins
d----         7/21/2008  10:01 PM            Home PC Restore CD

Note that from the remoting session on MediaCenterPC, I can now see the files shared from my Windows Home Server.  Woohoo!  It isn’t exactly as straight forward as I would like but it can be done.

April 05

Generating New-Object Wrapper Functions for an Assembly

One of the best parts of being a Microsoft MVP is having conversations with all the other, really bright MVPs.  The PowerShell team just recently added Doug Finke as an MVP – congratulations Doug!  It isn’t too uncommon for the PowerShell MVPs to challenge and push one another.  It is a great learning experience!

Over the weekend, Doug and I engaged in one of these and in the end we came up with a little bit of PowerShell script (V2 required for the generics support) that can automatically generate wrapper functions around the constructors of public .NET types in an assembly.  These wrapper functions are strongly typed (well mostly) and support generic types.  Here’s the script:

param($assemblyName)
Set-StrictMode -Version Latest

[Reflection.Assembly]::LoadWithPartialName($assemblyName).GetExportedTypes() |
% {
    $fname = $_.FullName
    $typeArgs  = @($_.GetGenericArguments() | %{"`$Of" + $_.Name})
    $typeDecls = @($_.GetGenericArguments() | %{"[string]`$Of" + $_.Name})
    $_.GetConstructors('Instance,Public') |
    % {
        $paramArgs  = @($_.GetParameters() | %{"`$" + $_.Name})
        $paramDecls = @($_.GetParameters() | 
            %{"$(if (!$_.ParameterType.ContainsGenericParameters) {"[$($_.ParameterType)]"})`$$($_.Name)"})
        if ("$paramDecls" -notmatch '\*') {
            $OFS = ','
            if ($typeArgs.Length -gt 0) {
                $genFname = $fname.Substring(0, $fname.LastIndexOf('`'))
                $decls = $typeDecls + $paramDecls
                @"
function New-$($genFname.Replace('.','')) {
    param($decls)
    New-Object `"$genFname$("`[$typeArgs`]")`" $paramArgs
}
 

"@            
            }
            else {
                @"
function New-$($fname.Replace('.','')) {
    param($paramDecls)
    New-Object `"$fname`" $paramArgs
}
 
"@
        
            }
        }
    }
}


NOTE: if you copy/paste this script, watch out for whitespace after the here strings’ opening sequence – @” – there shouldn’t be any. 
 

If you run it on mscorlib, it will product wrapper functions like so:

function New-SystemGuid {
    param([int]$a,[System.Int16]$b,[System.Int16]$c,[System.Byte[]]$d)
    New-Object "System.Guid" $a,$b,$c,$d
}



function New-SystemCollectionsGenericDictionary {
    param([string]$OfTKey,[string]$OfTValue)
    New-Object "System.Collections.Generic.Dictionary[$OfTKey,$OfTValue]"
}





function New-SystemCollectionsGenericList {
    param([string]$OfT)
    New-Object "System.Collections.Generic.List[$OfT]"
}

Then you can create a generic list like so:

PS> $list = New-SystemCollectionsGeneicList –OfT double
PS> $list.add(1.1)
PS> $list.add("two")
Cannot convert argument "0", with value: "two", for "add" to type "System.Double"

Effective PowerShell Item 15: Using the Output Field Separator $OFS

$OFS is the “output field separator” variable.  Whatever value it contains will be used as the string separator between elements of an array that is rendered to a string.  For example, consider the following array definition and subsequent rendering to string:

PS> $array = 1,2,3
PS> "$array"

What would you expect the resulting string to be?  Here’s the output:

1 2 3

How does PowerShell go about rendering elements of an array into a single string?  It is pretty simple as you would expect.  Each element is converted to its string representation.  The only other detail left is to determine what characters to use to separate each element in the final string.  The $OFS variable is not initially created by PowerShell and if it doesn’t exist, PowerShell uses a single space character to separate elements as you can see in the example above.  What is neat is that PowerShell gives you the ability change the separator string by setting the $OFS variable like this:

PS> $OFS = ', '
PS> "$array"
1, 2, 3

Note that the separator doesn’t have to be single character.  It doesn’t even have to be a string, but in the end whatever value that is assigned to $OFS is converted to a string e.g.:

PS> $OFS = $true
PS> "$array"
1True2True3

This is an admittedly weird example.  In the common case, you will just assign a string to $OFS like “, “ or “`t” or “`n”, etc. 

$OFS also works for multi-dimensional arrays e.g.:

PS> $array = new-object 'int[,]' 2, 3
PS> $array[0,0] = 1
PS> $array[0,1] = 2
PS> $array[0,2] = 3
PS> $array[1,0] = 4
PS> $array[1,1] = 5
PS> $array[1,2] = 6
PS> $OFS = ', '
PS> "$array"
1, 2, 3, 4, 5, 6

Unfortunately, $OFS doesn’t work so well for jagged arrays:

PS> $array = @(@(1,2),@(3,4))
PS> $OFS = ', '
PS> "$array"
System.Object[], System.Object[]

# Let’s try a different approach – not so satisfying
PS> "$($array[0]), $($array[1])"

1, 2, 3, 4

When I see folks use [string]::Join() or –join in version 2 of PowerShell, I wonder if it would be better to use $OFS and string rendering.  Here is an example I came across recently:

$typeDecls  = @($_.GetGenericArguments() | %{"[string]`$Of" + $_.Name}) –join ', '
$paramDecls = @($_.GetParameters() | % { "[$($_.ParameterType)]`$$($_.Name)" }) –join ', '

$decls = $typeDecls
$decls += $(if ($decls –and $paramDecls) { ', ' })
$decls += $(if ($paramDecls) { $paramDecls })

function New-$fname($decls) { … }

Using $OFS the script changes to:

$OFS = ', '
$typeDecls  = @($_.GetGenericArguments() | %{"[string]`$Of" + $_.Name})
$paramDecls = @($_.GetParameters() | % { "[$($_.ParameterType)]`$$($_.Name)" })

$decls = $typeDecls + $paramDecls

function New-$fname("$decls") { … }

In this example, the use of $OFS shines because you benefit by delaying the string rendering of the arrays until the last moment.  In this case, I wanted to keep both $typeDecls and $paramDecls as arrays so that they could be concatenated together and then rendered as a string containing a comma separated list.  If these two variables had been converted to strings earlier, as in the “before” script above, then you need special case logic in the event $typeDecls and/or $paramDecls are empty.

March 21

PowerShell Function Names

PowerShell allows you to use many different characters in your function names besides [_aA-zZ][_aA-zA0-9], which is the typical regex recipe for function and method identifiers in a fair number of languages.  However, in PowerShell you have a much larger palette of characters to choose from e.g.:

function ?? ($expr, $default = $(throw "Must specify default value")) {
if ($expr -ne $null) {
$expr
}
else {
$default
}
}

Function names like these can help you create operators for an internal DSL.  The primary downside is that the operator has to be used in a pre-fix manner e.g.:

PS> ?? ($env:LogDir) $env:temp
C:\Users\Keith\AppData\Local\Temp

Things get really interesting when you start to use mathematical symbols.  Check this out:

PS> function √($num) { [Math]::Sqrt($num) }
PS> √ 81
9
PS> function φ { (1 + (√ 5)) / 2 }
PS> φ
1.61803398874989

This is not really practical since the mathematical symbol characters (0x221A and 0x3C6) aren’t easy to type at the console but it shows the extent to which you can use radically different characters to name your functions.

psmdtag:script - function name

March 16

Image File Resizing Using the PowerShell Community Extensions

A reader asked me about using PowerShell to process image files.  While PowerShell doesn’t natively support doing this you could perform this task by using PowerShell’s support for .NET which supports image resizing.  However if you have the PowerShell Community Extensions (PSCX) installed you can do this pretty easily using cmdlets like so:

PS> Import-Bitmap .\Foo.jpg | Resize-Bitmap -Percent 50 | 
>> Export-Bitmap -path fooSmall.jpg -Format jpeg

Can you feel the power?!

psmdtag:cmdlet - Bitmap manipulation

March 15

Windows 7 Media Center Update

The problem we were seeing with movie DVD playback has been fixed!  NVidia released a Windows 7 driver update for the GeForce 6200 video card in late February.  I installed it two weeks ago and we haven’t had any problems with DVD playback since.

I’ve got four computers at home now running Windows 7.  A number of these are dual boot machines that can dual boot into Vista or Windows 7.  I’m finding it harder and harder to boot back into Vista.  The performance and reliability of Windows 7 has been great so far (other than the Media Center issues) and I have really adapted to the new taskbar.  I’m looking forward to the final release!

Customizing PowerShell ISE with Yank Line CustomMenu Item

I was excited to hear that the PowerShell ISE editor was based on the new WPF editor that will ship in Visual Studio 2010.  However I was disappointed when I couldn’t find one of my favorite shortcuts in the script editor: Ctrl+L a.k.a. yank line.  Fortunately the object model for the editor is capable enough to support this capability.  Here’s a pretty simple custom menu entry with an assigned keyboard shortcut (Ctrl+L) to perform a yank line in the editor:

   1: [void]$psISE.CustomMenu.Submenus.Add(
   2:     'Yank Line', 
   3:     {
   4:       $editor = $psise.CurrentOpenedFile.Editor
   5:       $line = $editor.CaretLine
   6:       $lineLen = $editor.GetLineLength($line)
   7:       if ($line -lt $editor.LineCount) 
   8:       {
   9:         $editor.Select($line, 1, $line + 1, 1)
  10:       }
  11:       else
  12:       {
  13:         $editor.Select($line, 1, $line, $lineLen + 1)
  14:       }
  15:       [System.Windows.Clipboard]::SetText($editor.SelectedText)
  16:       $editor.InsertText('')
  17:     }, 
  18:     'Ctrl+L'
  19: )

I find this handy for copying an entire line.  I yank the line that I want to copy to the clipboard.  Once it is yanked, I can paste it back as many times as I need.

psmdtag:ise - CustomMenu

March 08

Effective Windows PowerShell: The Free eBook

I’ve gotten some requests to turn my Effective PowerShell blog posts into booklet form which I have done.  I expect that this document will grow over time as I add new items.  If you have feedback (typos, suggestions, etc) please drop me a line.

Errata:
[Updated 3/12/09:]
Corrections from Aleksandar - thanks!
  *Page 9, PS> $proc =>
               PS> $procs
[Updated 3/16/09:] Correction from Thorsten - thanks!
  *Page 9, PS> $result | foreach {$_.GetType().Fullname}  =>
                    PS> $result = bar
                    PS> $result | foreach {$_.GetType().Fullname}

  *Page 12, Get-Item * | Where {$_.PSIsContainer} | Push-Location -passthru | Foreach {du; Pop-Location} => 
                Get-Item * | Where {$_.PSIsContainer} | Push-Location -passthru | Foreach {du .; Pop-Location}
[Updated 3/22/09:] Correction from Sergey - thanks!
  *Page 36 , "... it isn't obvious based on the ByPropertyValue ..." => 
                        
"... it isn't obvious based on the ByPropertyName ..."

psmdtag:book - Effective Windows PowerShell eBook

March 06

Effective PowerShell Item 14: Capturing All Output from a Script

Both version 1 and version 2 of Windows PowerShell have a nasty limitation when it comes to capturing *all* output from a script.  First up, within a script there is no way to redirect host (Write-Host), verbose, warning and debug message to a log file.  There is a mechanism within PowerShell that allows you to capture these streams of information - Start-Transcript.  At first blush, this seems promising however the wheels fall off pretty quickly primarily because Start-Transcript doesn’t capture the output of EXEs.  So all that output from compilers, build tools, etc doesn’t get captured.  That’s a huge, gaping hole.  Furthermore, Start-Transcript is really aimed at capturing your entire PowerShell session.  It isn’t particularly suited for script logging.  For instance, some folks including myself use Start-Transcript in their profile to capture an entire PowerShell session.  This is very handy when you need to look up how you did something previously which is possible because you can search your transcript files.  However, if you start a script that blindly calls Start-Transcript it will error.  You can only call Start-Transcript if it hasn’t already been started . There is no notion of nested transcripts.

If you find these limitations as annoying as I do, please vote on them via the Microsoft Connect site:

https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=283088&SiteID=99 
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=297055&SiteID=99 

For now, the best way to accomplish this is to use a host that can capture all PowerShell output.  It turns out that executing the script through another instance of PowerShell.exe will allow you to capture all the output.  For instance, consider the following script (test.ps1) that exercises the various output streams:

   1: $DebugPreference = 2
   2: $VerbosePreference = 2
   3: $WarningPreference = 2
   4:  
   5: hostname.exe
   6: Write-Host "host"
   7: Write-Output "output"
   8: Write-Error "error"
   9: Write-Verbose "verbose"
  10: Write-Warning "warning"
  11: Write-Debug "debug"


If you run the following you can easily capture all PowerShell output as shown below:

PS> powershell.exe -noprofile -file test.ps1 > test.log
PS> Get-Content test.log
HILLR1
host

output
C:\Users\hillr\Bin\test.ps1 : error + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,test.ps1
host VERBOSE: verbose
WARNING: warning
DEBUG: debug

Updated 3/7/09: Aleksandar pointed out that you can just use Powershell.exe.  No need to go through cmd.exe.  Thanks!

psmdtag:script - Logging output

February 02

XLinq PowerShell Module to Wrap XLinq API

This is pretty early stuff but I thought I would share it anyway.  I really like PowerShell as a .NET REPL.  It is the first way I’ll try an experiment with the various .NET APIs.  That doesn’t always work out and in the early CTPs of PowerShell I was having a hard time getting XLinq to work as I expected.  So I wrote this XLinq.psm1 module to make it a bit easier.  This does require CTP3 of Windows PowerShell v2.0 (or Windows 7 which has this version installed).  Note: you really have to resist the urge to use commas to separate arguments.  :-)  Here’s an example usage:

Contents of file: XLinqExample.ps1

   1: Import-Module XLinq
   2:  
   3: $doc = `
   4:     XDoc `
   5:         (XDecl -encoding 'utf-16') `
   6:         (XElem root `
   7:             (XElem author `
   8:                 (XAttr fname Michael) `
   9:                 (XAttr lname Crichton) `
  10:                 (XElem books `
  11:                     (XElem book `
  12:                         (XAttr title Prey) `
  13:                     ) `
  14:                  ) `
  15:             ) `
  16:             (XElem author `
  17:                 (XAttr fname Jon) `
  18:                 (XAttr lname Skeet) `
  19:                 (XElem books `
  20:                     (XElem book `
  21:                         (XAttr title 'C# in Depth') `
  22:                     ) `
  23:                  ) `
  24:             ) `
  25:         )
  26:     
  27: $path = [IO.Path]::GetTempFileName()
  28: $doc.Save($path)
  29: Get-Content $path
  30: Remove-Item $path    


It turns out that I put in more line continuation characters than needed but it was easier to just put them on every line than to sit and try to figure out if it was needed or not.  The following output is generated when the script above runs and uses the XLinq module functions like XDoc, XElem, XAttr, etc:

PS> C:\Users\Keith\Documents\PowerShell\XLinqExample.ps1
<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<root>
  <author fname="Michael" lname="Crichton">
    <books>
      <book title="Prey" />
    </books>
  </author>
  <author fname="Jon" lname="Skeet">
    <books>
      <book title="C# in Depth" />
    </books>
  </author>
</root> 

I’m not claiming this is the best way to manipulate XML in PowerShell, however if you want to do a quick experiment using XLinq this module comes in handy.  As always, if you find any bugs please drop me a line.

Update 02/13/2009:  Updated the module to handle pipeline input and scriptblocks (inspired by a similar module that Josh Einstein came up with).

psmdtag:module: XLinq
psmdtag:dotnet: Xml

January 28

Tail-Content – Better Performance for Grabbing Last Lines From Large (ASCII) Log Files

Necessity is the mother of invention, or in the case of Windows PowerShell, a new script.  I have a set of 23 large (28 MB) log files on a remote machine in which I need to verify that the last line of each of them is identical.  My first “naive” approach was to do this:

PS> get-content \\server\share\logs\*26_03.csv  | select -last 1

Yeah unfortunately that took so long that I killed it and set out to create a script that would “efficiently” tail a file.  Now my log files were ASCII encoded so it made the task much easier.  Bottom line is that there is FileStream object in .NET that allows you to start at the end of a file and work backwards.  The approach above using Get-Content requires that PowerShell get every single line from a log file with ~1,000,000 lines in it and over the network to boot. 

With FileStream you can read from the end of the file backwards.  Because my files are ASCII, that is very easy to do.  So I created a Tail-Content.ps1 script that you can download.  Note that it doesn’t work on Unicode encoded files and it doesn’t do active tailing.  However, it is very fast for large files.  There are a few interesting parts of the code to examine.  First, if you want to handle paths like PowerShell does, the snippets below show you how to setup your parameters to handle wildcard expansion and literal paths.  This does require that you are on version 2 of PowerShell:

   1: [CmdletBinding(DefaultParameterSetName="Path")]
   2: param(
   3:     [Parameter(Mandatory=$true, 
   4:                Position=0, 
   5:                ParameterSetName="Path", 
   6:                ValueFromPipeline=$true, 
   7:                ValueFromPipelineByPropertyName=$true)]
   8:     [string[]]
   9:     $Path,
  10:     
  11:     [Alias("PSPath")]
  12:     [Parameter(Mandatory=$true, 
  13:                Position=0, 
  14:                ParameterSetName="LiteralPath", 
  15:                ValueFromPipelineByPropertyName=$true)]
  16:     [string[]]
  17:     $LiteralPath,
  18:     
  19:     <elided>
  20: )

Note that the default parameter set is “Path” and the Path parameter accepts pipeline input by name and by value.  This means that raw strings will work as paths assuming they actually contain valid paths.  Also note that both parameters are of type string array.  The LiteralPath parameter is defined in a different, mutually exclusive parameter set named “LiteralPath” and it binds to pipeline input only by property name.  It is important that we also decorated the LiteralPath parameter with the Alias attribute “PSPath”.  This way output of Get-ChildItem (FileInfo) gets bound by property name to the LiteralPath parameter by virtue that PSPath is an alias for the same parameter.  This happens because there is no Path property on FileInfo but there is a PSPath property.  Remember that PowerShell extends the FileInfo type by adding the PSPath NoteProperty.

That sets up the parameters, now here is what you need to do in your Process function to handle Path parameters which could specify paths with wildcards in them:

   1: Process 
   2: {
   3:     if ($psCmdlet.ParameterSetName -eq "Path")
   4:     {
   5:         # In the non-literal case we may need to resolve a wildcarded path
   6:         $resolvedPaths = @()
   7:         foreach ($apath in $Path) 
   8:         {
   9:             $resolvedPaths += @(Resolve-Path $apath | Foreach { $_.Path })
  10:         }
  11:     }
  12:     else 
  13:     {
  14:         $resolvedPaths = $LiteralPath
  15:     }
  16:             
  17:     foreach ($rpath in $resolvedPaths) 
  18:     {
  19:         $PathIntrinsics = $ExecutionContext.SessionState.Path
  20:         
  21:         if ($PathIntrinsics.IsProviderQualified($rpath))
  22:         {
  23:             $rpath = $PathIntrinsics.GetUnresolvedProviderPathFromPSPath($rpath)
  24:         }
  25:         
  26:         Write-Verbose "<cmdlet-name> processing $rpath"
  27:  
  28:         #process file here
  29:     }
  30: }

On line 3 I test which ParameterSet is being used.  If it is the Path parameter set then we need to resolve the paths specified because they may contain wildcards.  I do that on line 9 using Resolve-Path.  Then on line 17 we iterate through each path and process it.  One other detail that you may or may not need to worry about is that $rpath at this point may contain a provider qualified path e.g. Microsoft.PowerShell.Core\FileSystem::C:\foo.txt.  These work fine with PowerShell however if you need to pass this path to a .NET object it won’t recognize that as a valid path.  So on line 21 I check to see if we have a provider qualified path and if I do I get the raw path using $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath as shown on line 23.  The rest of this script just does low-level byte reads from the end of the file. 

I went back and measured my original approach of using { Get-Content \\server\share\logs\*_26_03.csv | Select -Last 1} and it took ~13 minutes.  Using my Tail-Content script, it took < 1 second.  That is a speed up of about 1789x!

psmdtag:dotnet: FileStream
psmdtag:script: Tail-Content
psmdtag:sample: Advanced Function

Windows 7 Taskbar After Two Weeks

At this moment I have Windows 7 on the family room media center PC and dual booting on both my workstation and my laptop.  On the dual boot machines I find myself almost exclusively booting into Win7.  The only piece I’m missing is a driver for the fingerprint reader.  Hopefully that will come shortly.  Other than that, it is going great.  Both machines seem snappier under Win7 than they do under Vista. 

With respect to the new taskbar, I have to say that *I* really like it.  I still have concerns about the changing behavior of a mouse button left click on a taskbar icon depending on whether the app is already running or not.  Perhaps Microsoft is banking on the non-techies not really running multiple instances of the same app and power users figuring out that they can use either shift+click or middle mouse button click to always fire up a new instance.  I hope that is the case.  Still, I can’t help but feel that there are going to be folks resistant to change and not giving them the option of the classic taskbar is a mistake.  That said, if you don’t mind a bit of change and learning a few new tricks, I think you will find the new taskbar to be quite fun to use, maybe even somewhat addictive.  There are a number of really nice little touches like when you hover the mouse over the thumbnail of a window, all the other windows go transparent so you can more easily that window.  The ability of an taskbar icon to display progress is also very nice. 

There are also a number of new Windows key keyboard shortcuts in Windows 7 like Win+T, Win+<number> and Win+<arrow key>.  Brandon Paddock has a listing of them here, be sure to check them out – if you are a keyboard shortcut kind of person.

Updated 01-29-09: GPDuck on Twitter pointed me to these beta drivers for UPEK and AuthenTec fingerprint readers.  I’m using it on my x64 HP Laptop and it is working fine so far.

January 21

Windows 7 Media Center Update

A few weeks ago I repaved the family Media Center to the official Windows 7 Beta.  The results have been good.  We no longer get any “Copying Prohibited” errors thank goodness!  That was driving the family crazy.  We do notice some lingering issues though with the primary one being that we can’t play movie DVDs.  This one is odd because I can see all the various DVD files (IFO, etc) and the movie starts just a bit and then hangs.  I can’t get to the Root or Title menus.  Oh well, at least the kids can watch all their movies off of our Windows Home Server.  Other issues we notice is that if we leave Media Center playing TV, turn off the TV and go away for a while, when we come back the Media Center screen is blank and won’t come back.  You can Alt+F4 to close the Media Center app and re-launch it.  Unfortunately this bug seems to be new to the Beta.  We didn’t have this problem with the M3 build.  Finally we notice random sluggishness is the Media Center UI.  It sometimes comes back on its own and other times we need to kill the Media Center app and re-launch it.  Other than that, we are pretty happy with this build.  Just not having to worry about your shows not recording all the way because of the “Copying Prohibited” errors is a big relief.

Regarding the new taskbar, I’ve been using Windows 7 on my primary PC at home (dual booting with Vista) and I have to say I like it.  Except for the launching of a second instance of an application.  I have come to like the middle mouse button click (or Shift+Click) to force the new taskbar to launch a new instance of the application.  However I worry about this not being very obvious to the casual user.   Then again, perhaps it is only us power users that launch more than one instance of an application?

January 11

Could the new Taskbar Be the “UAC” of Windows 7?

Let’s face it.  Apple has had a significant impact on the negative perception of Windows Vista via their very successful I’m a Mac and I’m a PC switcher ads.  Apple has taken a few nuggets of truth in terms Vista issues like UAC, most of which have been fixed in SP1 except UAC, and paraded them in front of the world in a attempt to get folks to switch from Windows to the Mac.  Given what they spend on these commercials and increasing market share (still small though) I would say that it has been working for them.  On the other hand we all know that advertising isn’t about pure truth.  Many ads stretch the truth and some outright bend it to the snapping point.  So the question is this.  Shouldn’t Microsoft be taking extreme precautions *not* to give Apple any more ammunition for Windows 7 than they already have?  I mean, you can already expect Apple to harp on Windows 7 as being nothing more than a warmed over version of Vista.  Just take a look at the version number.  Vista is 6.0 and Windows 7 is 6.1 – it’s a .1 release over Vista.  How can that be significantly different than Vista?

I’m afraid this new Taskbar a.k.a superbar is going to give Apple plenty of ammunition.  The point of this post is to question the sanity of not providing a classic mode for the Taskbar in Windows 7.  You might ask, why do that?  Well, I agree with Paul Thurrot, the new Taskbar has some serious usability issues.

I've done plenty of user centered design and usability tests in my job.  I just did an albeit quick and informal Windows 7 Beta taskbar test with my wife (non-technical XP user) and the results weren't great.  Note that I’ve setup Windows 7 to not hide labels.

1. Task: Start IE from the taskbar.  Result: She finds the IE button, press it, done.
2. Task: Start another IE from the taskbar.  Result: She gets frustrated and gives up after a two minutes.  Notes: She presses the same IE button again, IE disappears.  She becomes frustrated wanting to know why IE closed when she expected it to start another.  After all, it looks like the old quick launch toolbar which always launched a new instance of the app.  This is a fundamental UI issue: - be wary of changing the semantics of an actionable UI element (button in this case).  She starts to want to give up here so I press her and ask what else she might do with the IE task bar button.  She mentions right-clicking, so I suggest she try that.  She brings up the jump list but by that point she's so annoyed that it becomes wise that I just shutdown my little test.  That's the problem with doing these tests with your spouse.  :-)

Suffice it to say the wife acceptance factor for the taskbar is very low and she hasn't really gotten far into Windows 7.  That's the problem that makes me fear for it’s acceptance. This new taskbar is the first hurdle you have to get over to appreciate the other niceties in Win7.  But now, she's already got a bad taste in her mouth for Windows 7 and to be honest she is one of those folks who doesn't like Office 2007 either because of the ribbon UI. 

I'm more of a power user and I can respect MS trying to make Windows more approachable for the non-techies.  As long as we power users can get some  advanced options to tweak Windows to our advanced needs, we’re good.  However I think there are some fundamental UI design tenets being broken here.  Like changing the semantics of a taskbar button depending on whether the app is running or not.  That's a *huge* mistake IMO.  I also think it is a productivity hit because starting a new instance of an application, once you realize what's going on, is now:

  1. mouse move
  2. right-click
  3. mouse move
  4. click

It is now twice as hard to start a new instance of an application if it is already running.  Tell me Microsoft, from your telemetry data, how often do folks fire up more than once instance of an app?  Hmm, let's take IE and just one data point - me.  Even with IE7's tab support I tend to have anywhere from 3 to 7 instances of IE running at once.  BTW, I do know about the Shift+Click shortcut but I don't think that having the average computer user rely on that is viable in this case.

FWIW I don't think the discoverability of the jump list is that big of a deal if and *only if* you don't need to use the jump list to start a second instance of an application.  The jump list is very much like a right-click context menu so having to right-click to access it, feels natural.  One minor quibble with jump lists, why does the top item in the common section say <app name> instead of “Start <app name>”?  I would think that seeing an action like “Start Internet Explorer” in a list of actions makes more sense than seeing a noun “Internet Explorer” in a list of actions.

I do not want to come across as bashing everything about the new taskbar.  In fact, there is a lot I like about it.  I really like the jump lists, the improved thumbnails, the thumbnails with mini-toolbars, button icon overlays, coloring and progress indication.  I can even appreciate the desire to combine the quick launch buttons with the active task buttons to reduce redundancy and clutter. 

I can think of at least one reasonable solution to this *if* you’re in the mode where you are not hiding labels.  What if the icon part of the button doesn’t change its semantics.  It always fires up a new instance.  Once an app instance is running, then you get a different actionable area (i.e. button) right next to the icon button perhaps with a very subtle vertical divider. The new button wouldn't have any icon so the overall width wouldn't increase – again assuming we aren’t hiding labels.  In fact, if you have more than two instances running the width would actually be less due to the fact that there would only be one icon.  This would also require less reliance on thumbnails to select from multiple running instances of an app.

Frankly, if Microsoft were to ship Windows 7 today, I think this new taskbar could dog it like UAC has dogged Vista.  I can just see the Apple commercials now hyping up how people hate *the* primary piece of UI in Windows 7 and how you've got *NO* choice.  You either take the new taskbar or you leave it, er Windows 7 and take a Mac for a spin.  I can see the Seinfeld soup Nazi inspired commercial now - "NO CLASSIC TASKBAR FOR YOU!!!". 

In summary, I think Microsoft would be insane to ship Windows 7 without a classic taskbar mode.  Vista tried to foist UAC upon folks, which I think was the right thing to do if for no other reason than to get ISVs to fix their software to run correctly as a standard user.  However it turned out badly for Vista perception and adoption.  Office 2007 also took this all or nothing approach with the ribbon UI.  But Office doesn’t have much in the way of a serious competitive thread yet.  I’m not so sure that’s the same with Windows anymore, at least not in the consumer space.  Apple has proven it can steal large chunks of market share in the consumer space as evidenced by the success of the iPod and the iPhone.  And they're chipping away at the OS market share with their Vista advertising campaign and an OS that is apparently simple to use.  Disclaimer: I haven’t used a Mac in 15 years but I keep hearing from friends that they are easy to use.  Personally, I wouldn't want to give Apple any more ammunition than they already have for Windows 7 switcher ads.

January 01

Renewed as Windows PowerShell MVP for 2009

I got a very nice email today telling me that I have been awarded as a MVP for Windows Server - Admin Frameworks (aka Windows PowerShell).  Woohoo!  Not sure if I’ll get to make it to the summit this year because of an uncertain job situation but I’m going to try.

December 11

Little Things in PowerShell - Determine Timespan of Files in a Dir

Often it is the "little things" that put a smile on your face.  PowerShell does that for me a lot.  Take for instance a simple little problem I ran into today while unit testing some code that generates log files.  I wanted to know how long it took to write all the log files to disk.  Due to the way the code works on a background thread, it wasn't particularly easy to use a System.Diagnostics.Stopwatch to do this.  You could do this manually by inspecting the file dates (DateCreated and DateModified) in Windows Explorer but it only shows resolution down to minutes and I have to do the math myself.  No good.  Well this information is easy to figure out with PowerShell.  Just CD into the log dir and execute:

PS> $start = dir | foreach {$_.CreationTime} | sort | select -first 1
PS> $stop  = dir | foreach {$_.LastWriteTime} | sort -desc | select -first 1
PS> $stop - $start

Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 10
Milliseconds      : 734
Ticks             : 107341689
TotalDays         : 0.000124238065972222
TotalHours        : 0.00298171358333333
TotalMinutes      : 0.178902815
TotalSeconds      : 10.7341689
TotalMilliseconds : 10734.1689

:-)

Yes PowerShell can do all sorts of acrobatics WRT managing and querying a computer but it can also do the simple stuff in a pretty straight forward manner.

December 01

Windows PowerShell Training Webcast

Sign up for some free PowerShell training via this TechNet webcast.  Here’s the overview:"

In this webcast, we provide an introduction to Windows PowerShell for IT professionals and show how to automate client administrative activities in the Windows Server 2008 and Windows Vista operating systems. We explore the features and capabilities of Windows PowerShell, describe customer scenarios to manage day-to-day server and client administration activities, and discuss command-line syntax usage.

Presenters: John Baker, IT Pro Evangelist, Microsoft Corporation, and Yung Chou, IT Pro Evangelist, Microsoft Corporation

I like these because you usually get some decent info for very little investment and if it doesn’t turn out to be right for you, you can bail easily with very little time lost.

November 13

Windows 7 Media Center Update

Well my cheap-o ($50) 500 GB hard drive went belly up with a “S.M.A.R.T status bad” error after just two days – RMA time.  So it was off to Best Buy for a replacement drive.  I completely reinstalled Windows 7 and amazingly this time it recognized my Audigy2 sound card and my modem.  And without me installing any of the original Gateway drivers the front panel HID buttons work including the Home button *and* the IR receiver works!  Excellent.  The only thing I didn’t get back was the front panel display that mostly shows the current time.  Definitely can live without that. 

Now we are still running into the “Copying Prohibited” errors watching live TV and this is starting to annoy the family. Fortunately you can switch channels, wait for a bit and then switch back to get around this blockage.  These seem to be popping up a lot during commercials.  One other issue is that I haven’t had any luck getting a DVD movie to play.  That kind of sucks except that the kids mostly watch movies off the DVD library.  And I can watch DVDs via our XBOX 360 – as long as I crank the volume so I can hear the movie above the sound of the XBOX fan noise.

November 11

PDC 2008 Recap Presentation

Jeff Certain (VB MVP) and I gave a PDC 2008 recap last night at the Northern Colorado .NET User Group.  It went pretty good given the short notice.  Jeff contacted me earlier that day and told me the presentation had been pushed up a month because another speaker couldn’t make it.  :-)  Here are the slides:

Team Foundation PowerShell PSSnapin in October Team Foundation Power Tools Drop

Oh thank you, thank you TFS team!!!  This is a great development because it enables version control queries for mere mortals (ie those of us not well versed in SQL Reporting Services).  It also enables easily scriptable queries.  With the October Team Foundation Power Tools drop, you get a PowerShell console icon in the start menu or you can just add the following to your profile:

Add-PSSnapin Microsoft.TeamFoundation.PowerShell

Once you’ve done that, here are the new cmdlets you get:

  • Add-TfsPendingChange
  • ConvertTo-FixedByte
  • ConvertTo-FixedPath
  • Get-TfsChangeset
  • Get-TfsChildItem
  • Get-TfsItemHistory
  • Get-TfsItemProperty
  • Get-TfsPendingChange
  • Get-TfsServer
  • Get-TfsShelveset
  • Get-TfsWorkspace
  • New-TfsChangeset
  • New-TfsShelveset
  • Remove-TfsPendingChange
  • Remove-TfsShelveset
  • Restore-TfsShelveset
  • Select-TfsItem
  • Set-TfsChangeset
  • Update-TfsWorkspace

Now that you have the Team Foundation snapin loaded, you can start doing some interesting stuff like finding out who has pending changes older than 30 days:

PS> Get-TfsPendingChange . -User * -Recurse | 
where {$_.CreationDate -lt (get-date).AddDays(-30)} |
select OwnerName -expand PendingChanges |
format-table Filename, ChangeType, OwnerName, @{l="Server Folder";e={$_.ServerItem}} -auto

Or say you want to see the level of checkin activity over the past 30 days:

PS> $history = Get-TfsItemHistory . -Recurse -Stopafter 1000 | 
Where {$_.CreationDate -gt (get-date).AddDays(-30)} |
Sort CreationDate |
Select Owner,@{n='CreationDate';e={$_.CreationDate.ToShortDateString()}}
PS> $history | Group CreationDate -noelem
Count Name ----- ---- 4 10/12/2008 7 10/13/2008 103 10/14/2008 67 10/15/2008 23 10/16/2008 13 10/17/2008 3 10/19/2008 3 10/20/2008 23 10/21/2008 19 10/22/2008 31 10/23/2008 67 10/24/2008 10 10/27/2008 13 10/28/2008 29 10/29/2008 7 10/30/2008 4 10/31/2008 3 11/3/2008 2 11/4/2008 7 11/5/2008 10 11/6/2008 3 11/7/2008

If you have the excellent PowerGadgets, then you could do this:

PS> $history | group CreationDate | Out-Chart -Caption "Checkins/Day" -Size 480,320 -modal

And get this nice graph:

image

Now if I’m a project manager on a large team, I might want to see “who” is checking in a bunch of code right before a deadline.  That is easy enough:

67> $history | Group CreationDate | 
Foreach { "$($_.Name) - Total Checkins: $($_.Count)";
$_.Group | group Owner |
sort @{e={$_.Count};asc=$false},Name |
Format-Table Count,Name -auto }
10/12/2008 - Total Checkins: 4 Count Name ----- ---- 4 Acme\moe 10/13/2008 - Total Checkins: 7 Count Name ----- ---- 3 Acme\moe 2 Acme\socrates 1 Acme\curly 1 Acme\optimus

Querying is an especially powerful aspect of PowerShell and teamed with these new Team Foundation version control cmdlets, you have access to some interesting information.

psmdtag:snapin: Team Foundation Power Tools
psmdtag:snapin: TFPT

November 07

Taking Windows 7 Media Center for a Spin

After getting back from the PDC, the Windows 7 excitement drove me to upgrade my old Gateway FMC-901X running MCE 2005 (pre-rollup 2) to Windows 7 Media Center.  I bought 2 GB of memory for it and a new 500 GB harddrive (so I could preserve the original MCE 2005 setup).  The Win7 install was a breeze and went pretty fast.  But getting the Vista Audigy2 driver on there required me to trick the installer program into thinking it was installing on Vista (thank goodness for that “Compatibility” tab on the file Properties dialog).  Unfortunately the front panel display driver doesn’t seem to work.  I could install it but the built-in IR receiver doesn’t work anymore.   Oh well, I’m buying an inexpensive Pinnacle MCE remote that comes with an IR receiver.  That should take care of that problem.  Curiously, the front panel button (HID) driver does seem to work, well except that the “Home” button doesn’t work.

Setting up W7 MCE was also pretty easy.  It even recognized my Hauppauge PVR500 card right away - nice!  I also setup my XBOX 360 as an extender which was very straight-forward.  I pointed W7 at my Windows Home Server music, photo and DVD collection and it all works great.

But (you knew there was a but coming, right?), we keep getting these "Copying Prohibited – Protected Content" messages which stops "live" TV in the middle of a show.  I was trying to watch the Browns/Broncos game last night and it did this several times at what appeared to be commercial breaks.  I did a bit of research and came across the recent KB950126 and KB955519 patches.  I downloaded the Vista version of these but they won't install on Windows 7 – not too surprising.  Any chance we could get these updates (even as a hotfix) on Windows 7?  Pretty please with sugar on top.  :-)  My family would love to help you collect CEIP data (yes, I turned that on) using Windows 7 Media Center.

BTW *this* kind of crap is why folks despise and I mean DESPISE DRM.

November 04

Windows 7 “Personal Documents” – You’ve Got to Be Kidding Me

Take a look at this screen from the PDC M3 Win7 build:

image

WTF??? Is that schizophrenic or what?  Fortunately, at the very least, the real folder name appears to be “Documents” from the command line.  Whew!  However the Windows Explorer can’t seem to make up its own mind on what to call it. 

Here’s my two cents – Vista did a good, no GREAT, service by nuking all the *STUPID* “My <blah>” prefixes.  Please don’t let Win7 introduce an even worse prefix - “Personal”.  OK, I’ll get off my soapbox now.

 

Keith Hill

Occupation
Location
Interests

Zune Card

 
No folders have been shared yet.