Wednesday, February 15, 2012

PS (2) ISE Transcript

The PowerShell 2.0 ISE throws a "NotImplemented: (:) [Start-Transcript], PSNotSupportedException" exception.

I would have expected that the Transcript would be implemented outside the Host and call both an Add-Content and a Write-Host.  I wonder what could have been intended for the Host to use the output from that couldn't be done by a handler in the Write-Host. 

So when calling in production scheduler of powershell.exe the transcripts are fine.  When I run in the ISE, it doesn't work so well.  Of course all of the output is visible on the OutputPane, but the red exception text and lack of per run detail left me unfulfilled.

...Now is there a way to clobber the default  stop-transcript then call the original.

try {
    Start-Transcript -Path "C:\Transcript.txt" -Append 
} catch {
    clear # only want this run to output.

#profile function
# Todo:  Check Verb
Function  Export-ISEOutputToWindow
 $transcriptHeader = @"
Windows PowerShell ISE Transcript Start
Start Time: $(get-date)
UserName: $env:username
UserDomain: $env:USERDNSDOMAIN
ComputerName: $env:COMPUTERNAME
Windows version: $((Get-WmiObject win32_operatingsystem).version)
Transcript started. Output file is $logname

    # Could Pass Transcript File name to Add function and modify the process to Append.... I should do that.
    $Outfile = $psise.CurrentPowerShellTab.Files.Add(); 
    $Outfile.Editor.Text = $transcriptHeader + $psise.CurrentPowerShellTab.OutPut.Text;

#For use
try {
    stop-transcript ;
} catch { 

...Now is there a way to clobber the default  stop-transcript then call the original.

Will suggested that I look at  This had a ISETranscript that pulled the detail from the output pane.  I combined this with a function I saw yesterday on poshcode that implemented an Out-ISEFileTab process.  Combined they make the above.

Tuesday, February 14, 2012

Handy Profile addition PSISE extension.

For the Microsoft.PowerShellISE_Profile.ps1, this will add a menu item to directly open two of the profile ps1.

# Single quote for first item makes sure that the "$" is included in the menu.
$profileMenu = $psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add('$Profile',$null,$null)
$profileMenu.Submenus.Add("Profile",{$psise.CurrentPowerShellTab.Files.Add($profile.CurrentUserAllHosts)},$null)  | out-null
$profileMenu.Submenus.Add("ISE Profile",{$psise.CurrentPowerShellTab.Files.Add($profile.CurrentUserCurrentHost)},$null)  | out-null

Personally I am replacing the profile variables with production scripts that I manual run if the scheduled run sends me an error email.

$profileMenu = $psISE.CurrentPowerShellTab.AddOnsMenu.Submenus.Add('$Profile',$null,$null)

Thursday, February 9, 2012

Another PS1Batch approach

For some reason the Win7 Home Premium at home and my Win7 Pro at work, don't handle batch file errors the same.

Last nights approach the batch would display an error that "<# was an invalid command line, but would go to the next line and keep kicking.  At work, the whole batch file terminates.

I tried a few variations on Commenting the line, but all of them either killed the PS1 on the load error checks, or had the same effect.

But my command shell at work doesn't care about the following.

$Batchfile = @"
copy %~dpn0.BAT %~dpn0.ps1
powershell.exe -Noprofile -ExecutionPolicy Unrestricted -file %~dpn0.ps1
DEL %~dpn0.ps1

Wednesday, February 8, 2012

Self Running PowerShell File

Will ( and I had some email back and forth today about custom installers using PowerShell.  In this correspondence, I was trying to think of the most intuitive way to execute a PowerShell script on an unknown system.

One of these, I thought was academically interesting... and Hence, the PowerShell batch script.

Save this to a batch file : Test.bat

copy %~dpn0.BAT %~dpn0.ps1
powershell.exe -Noprofile -ExecutionPolicy Unrestricted -file %~dpn0.ps1
@DEL %~dpn0.ps1

Now the issue is that it is making a copy of itself.... but it will run.

- EDIT - Had an error at work, see

Monday, February 6, 2012

Mapped Drive Aware Prompt

    function Prompt {
        # if current Drive is a mapped drive, show the mount point
        # If you add a mapping it will not show unless you:
        # $Global:Drives = $null
        if ($Global:Drives -eq $null) {
            $Global:Drives = @{ }; Get-WmiObject Win32_LogicalDisk | %{ $Drives.Add($_.DeviceID,$_)};      
        $Loc = $(Get-Location)
        $LocExtended = $Drives[$Loc.path.substring(0,2)].ProviderName + ' ' + $Loc
        $(if (test-path variable:/PSDebugContext) { '[DBG]: ' } else { '' }) + 'PS ' + $LocExtended + $(if ($nestedpromptlevel -ge 1) { '>>' }) + '> '