Keith's profileKeith Hill's BlogPhotosBlogListsMore Tools Help
    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 get 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> Enable-PSRemoting

    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>

    Note: If you are trying to get PowerShell 2.0 remoting working on an XPMode virtual machine (you know the one you get for free with Windows 7 Pro or higher) then you need to enable Classic share & security model for local accounts like so: 

    1. Run Secpol.msc
    2. Navigate to Security Settings -> Local Policies -> Security Options -> "Network access: Share and security model for local accounts
    3. Change it to "Classic" mode.

    Now try re-running Enable-PSRemoting and it should work.

    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.