Blogroll

Search

Fast New PSCustomObject.

August 15th, 2009 by Karl

Given the context on the last few posts. I’ve made a simple helper method in C# that can take a simple powershell hashtable and create a PSCustomObject based on it. Here is an example of how you can call it.

[snapinini.newobjecthelper]::newObjectFast(@{name="karl";age=31;now = [datetime]::Now})

very simple and its at least 6 times faster than the closest other technique in powershell. Most of hte overhead is in creating the hashtable. (otherwise its 90 times faster). The hashtable syntax is very convenient however maybe even its overhead is too much and we deserve a better way.

Here is the C# method. Its pretty basic stuff.

public static PSObject newObjectFast( Hashtable noteproperties )
        {
            PSObject obj = new PSObject();
            if (noteproperties != null)
                foreach(DictionaryEntry item in noteproperties)
                    obj.Properties.Add(new PSNoteProperty((string)item.Key,item.Value));
            return obj;
        }

- Karl

Posted in Bare Metal, Gotchas Etc, Powershell, performance, pscom | 3 Comments »

PowerShell ISE-Cream

February 5th, 2009 by Karl

A while back I threw together a few scripts to enhance PowerShell V2 ISE experience that added some PowerShell Analyzer like features . They were a natural fit as ISE (Intergrated Scripting Environment) is like a WPF-based stripped PowerShell Analyzer like with its multiple runspaces, editors, and immediate command area.

The extensibility model of ISE has caught on, and many people have been writing some great scripts adding hotkeys to do every what not you could imagine, so I’ve decided to start a codeplex project with the punny name “PowerShell ISE-Cream” . The Goal of this project is first to gather a huge variety of functionality that various people are willing to share, refactor it into production quality functions, with extensive error handling, and packaged in V2 Modules, and finally incorporate it in a way that users can easily turn on and off different features through a consistent configuration.

Right now however we are just going to gather whatever scraps there are, whether they conflict with each other or not, and anybody passionate about this can join the project, as we sculpt it hopefully into something both useful and beautiful.

Doug Finke has already joined the club with his Expand-Alias and Expand-CurrentAlias functions, and there are quite a few other functions that people i know are willing to share, so it should be good.

We’ll be brainstorming and deciding on a bunch of design issue, you can join the conversation on the first one in this discussion thread.

The PowerScripting Podcast tonight (Thursday 5th Feb 2009) will be talking about ISE. There should be a number of MVPs (including myself) and some PowerShell Team staff calling in. It Should be fun.

-Karl

Posted in PSV2, Powershell, pscom | 1 Comment »

Tobias and Idera make PowerShellPlus 2.1 Beta Public.

February 3rd, 2009 by Karl

Well its been six months or more since our baby PowerShell Plus grew up, left home and moved in with Idera. Well its been progressing nicely, and we are happy to see the vision being fulfilled,nd even expanded, with a successful commercial product. Go Tobias – Go Idera.

Anyhow, I’m pretty much going to reblog the content from Tobias’s blog entry below. If you haven’t tried PS+ yet. I recommend wholeheartedly that you do. It really is about 3 generations and a couple of years ahead of anything else out there. Other vendors have only recently implemented “borrowed” features that have been in PowerShell Analyzer and PowerShell Plus since 2006.

http://powershell.com/cs/blogs/news/archive/2009/02/02/powershellplus-v2-1-beta-is-live.aspx

———————————————————

Exciting news! Effective immediately, PowerShellPlus v2.1 Beta is live and publicly available! Below you will find exciting information about an early look at what the PowerShellPlus team has been working on.

PowerShellPlus version 2.1 introduces several new and cool features focused on reducing the PowerShell learning curve, increasing the productivity of PowerShell development and exercising the capabilities of PowerShell 2.0. The new features include:

  • Code sharing – Enables you to leverage the wealth of scripts that reside in the PowerShell.com and PoshCode.org libraries. Increase your productivity by quickly and easily searching and grabbing the scripts from those libraries. You can also submit your own scripts to the PowerShell.com library directly from PowerShell Plus Editor
  • Visual Basic support – The PowerShell Plus Editor can now edit and run Visual Basic scripts
  • STA mode support – Enables you to produce pretty cool looking GUI’s with Windows Presentation Framework (WPF) using PowerShell 2.0.
  • PowerShell Assembly Detection – Gives the Learning Center an auto-upgrade path if PowerShell v2 CTP3 is detected and then displays the most up-to-date information
  • Learning Center Auto-Load – Makes searching for a request with a single match much easier to use since the topic will load automatically, saving extra keystrokes
  • Cmdlet parameter position – Shows you additional information in the code completion popup window about parameters including position and type
  • Console size overlay – Shows you the height and width of the Console when you resize it
  • Additional Sample Scripts - Active Directory, IIS 7.0 and MySQL
  • PowerShell v2 CTP3 Support – Including Block Comments and the $Profile variable

How to get the New Version

Use the link at the bottom of this page to download the installation package, but before you do please read the following disclaimers, warnings and other general portents of doom.

  • This software is a pre-release version and should not be deployed in a production environment. It will not work the way a final version of the software does. Features will change before the final release
  • If you already have a PowerShellPlus license we recommend that you install this version on another machine, but we do support an upgrade in place your production version.
  • If you upgrade your production version of 2.0 we will not overwrite any user customizations that have been made to PowerShellPlus but we do recommend you make a copy of the Sample scripts if you have modified them.
  • A list of the changes is provided in the Release Notes in the Installation Package.
  • This release is designed to provide the PowerShellPlus community with a preview of key features coming in 2.1 and to solicit feedback about them. This Technical Beta is not supported by the Idera Technical Support Team. Please visit the Beta Place: http://powershell.com/cs/forums/93.aspx

System Requirements

  • Microsoft Windows PowerShell Version 1 or Version 2 CTP2 or CTP3
  • Windows XP, Server 2003, Windows Vista, Server 2008, Windows 7

Installation Instructions

To install PowerShellPlus:

  1. Click the link at the bottom of this page and complete the download form
  2. An email will be sent with instructions on how to download the Beta.
  3. After downloading the Beta, unzip the contents of the Installer package.
  4. Read the Release Notes for late breaking information about the Beta.
  5. If you are upgrading from PowerShellPlus 2.0 make that you copy the Sample Scripts to another location, if you have modified them.
  6. Run the Setup.exe program to install PowerShellPlus 2.1.

Grab your copy now:

Download Here

For feedback, bug reports, suggestions and discussions regarding this beta release, please visit and use our Beta Place:

http://powershell.com/cs/forums/93.aspx

Enjoy!

-Tobias

Posted in PSV2, Powershell, Powershell Plus, pscom | 1 Comment »

Debugging Realtime by Ear. Adding one more dimension

January 30th, 2009 by Karl

I am amazed by people who can pick out every single note and chord when listening to music, and others who can totally play by ear. However even the musically inept and tone-deaf of us can detect an odd note, especially if its in a tune we know, but often even in an unknown tune, we can detect an out of place note, that isn’t in the scale, whether we know what a scale is, or even what key the song is in.

So what’s this got to do with debugging? We’ll mostly it’s the real time aspect. You are able to process a lot of information (notes), in context, and are able to discern real-time what is out of place and wrong.

Compare that to typical debugging. You might use checkpoints, and tracing through code, slowing down the execution often a million-fold, tediously stepping through each line of code, looking here and there.
Alternatively you might be processing log output, whether a debug stream in your IDE, console output, or something else. However just getting those messages to somewhere you can display can be hard when threading, and you aren’t in the GUI thread etc.
Additionally you are having to interpret this, often after the fact, and you can often miss things when lots is going on. How often , especially when finding a rare threading bug, are you running something 10 or more times, and maybe logging 10 or so different events each time. Going through the log takes time, and sometimes you miss the cue.

So, is debugging with sounds going to change and revolutionize everything? No its just another tool in a really great toolkit we have these days.

I thank my friend Oisin Grehan (http://nivot.org ) for inspiring this as I don’t think I’ve used sound in debugging since the my  Demoscene  days when I was coding MOD players. Mod Players . So naturaller the tracker syntax has inspired me a bit.

 

So how does this work. Well work out the steps you are listening to, and maybe things you particularly want to catch, play the notes over and over a few times so you know mentality what to expect, then just start running you code, and listen to what actually IS happening, and then maybe at certain times you might make a certain note MEAN something (like middle  C  for TRUE function result and middle A for FALSE), but I typically just use notices to indicate execution flow, and if I want to know some value, I ask windows Speech API to help me out.

function Play-Note([string]$note,[int] $duration = 5)
{
  if (!($note -match '(\d+)')) { $note+='4' };[void]($note -match '([A-G#]{1,2})(\d+)')
  [console]::Beep((440 * [math]::Pow([math]::pow(2,(1/12)),
    (([int] $matches[2]) - 4)* 12 + $( switch($matches[1])
  {  'A'  { 0 }  'A#' { 1 }  'Bb' { 1 }  'B'  { 2 }  'C'  { 3 }  'C#' { 4 }  'Db' { 4 }
     'D'  { 5 }  'D#' { 6 }  'Eb' { 6 }  'E'  { 7 }  'F'  { 8 }  'F#' { 9 }  'Gb' { 9 }
     'G'  { 10 } 'G#' { 11 } 'Ab' { 11 }
  }))),$duration * 100 )
}

So two things. I’ve based the notes on common tracker syntax including the octave. so middle A is A4 , then you have things like F#3 etc. however if as with everything PowerShell we want pithy, so if you don’t put an octave number then it will be 4 by default.

play-note C ; play-note Eb ; play-note “C#”

also i included a duration, so if the want the note to be anything but the default half a second put that as a parameter

play-note Eb4 20

and you’ll get an E flat for 2 whole seconds. You may ask why I don’t use seconds or milliseconds, because those are our official measurements in this 1,000,000 3 grouped western world. Well the reason is pithiness (something i love in my scripts, but aren’t good about when it comes to blogging). Typically i want a note between say 300 milliseconds and 5 seconds. so if i used milliseconds i’d always have to have those 2 or 3 extra zeros, while if i used seconds I’d be doing things like 0.4 and 1.5. If Japanese and Chinese we often communicate number differently, and group them differently. so there is a word for 10,000 , so to say 15 thousand you may say 1 (character for 10,000) 5.

So what about voice. You can use a very simple function using the SAPI COM objects such as:

function Speak-words ([string]$words,[bool]$pause = $true)
{   $flag = 1
    if ($pause) {$flag = 2}
    $voice = new-Object -com SAPI.spvoice
    $voice.speak($words, [int] $flag)
    # 2 means wait until speaking is finished to continue
}

Typically though i don’t create a $voice everytime , but kept a reference somewhere , like in my V2 module. Others however have done more impressive things with the voice in powershell ( http://poshcode.org/667 | http://huddledmasses.org/powershell-speaks/ ).

So now you may want a way to play more notes and speak more words together, in a pithy line. you can just use play-notes

function Play-Notes
{
$defaultduration = 5;if($args[0] -is [int]) {$defaultduration = $args[0]}
for($i = 0;$i -lt $args.length;$i++)
 {    $duration = $defaultduration
    if ($i -lt $args.length-1) { if ($args[$i+1] -is [int]) {$duration = $args[$i+1] } }
    if ($args[$i] -is [string]) {
        if ($args[$i].startswith("!")) { speak-words $args[$i].replace('!','') } else
        { play-note $args[$i] $duration }
        }
 }
}

And with this you can simply pass in a list of notes, which will be played with a default duration, unless you choose to specify a duration after the note.

play-notes A B C 20 E 10 B 10

play-notes F5 2 E5 2 D5 2 C5 2 B5 2 A5 2 G 4 F5 2 E5 2 D5 2 C5 2 B5 2 A5 2 G 4

If you want to change the default duration to reduce the redundancy above, just put that number as the first parameter

play-notes 2 F5 E5 D5 C5 B5 A5 G 4 F5 E5 D5 C5 B5 A5 G 4

and finally if you want some speaking in there, just have your string start with an exclamation mark!

play-notes "!here we go now" Db5 Db Eb Gb Ab "C#" 6 !YEAH

But of course most of the time you will have speaking, you’ll want it to say something you don’t know like a variable or the results of a formula.

play-notes A!$([datetime]::now) C

So you can get all these functions together at poshcode. ( Script | Download )  . We’ll time will tell if this will stay a habit of mine or be a fad. Additionally if you wanted to take this seriously you’d probably want to use something better than console.beep , maybe you’d use a full on MOD engine like http://fmod.org/ and having it running iringn a different process, and have a very cpu lightweight IPC going on, and different threads could play different channels, so between threads you could debug via Chords if you really have the ear for it.

WARNING, NOT A CUBICLE FRIENDLY DEBUGGING TECHNIQUE WITHOUT HEADPHONES UNLESS YOU WANT YOUR COLLEGUES TO DEBUG YOU.

Enjoy,

Karl

Posted in Powershell, pscom | No Comments »

PowerSMUG – Syncronize folders on your machine with Smugmug.

January 12th, 2009 by Karl

In ShellTools most of you were familiar with only Tobias Weltner and Myself, however behind the scenes was a critical cofounder – Eddie Hadjes. Below is a script Eddie wrote a few months back to synchronize data between your local folders and the excellent SmugMug web album service. You can always get the latest version and info on our wiki.

Script @ PoshCode: View Script | Download

Share on Facebook

 

—-

# PowerSmug photo sync script v1.0
# This PowerShell script will syncronize a folder of images with a users SmugMug account
# Please set the appropriate variables in the User Defined Variables region
# For more information visit http://shelltools.wik.is/Other_Projects/PowerSmug
#
# Images are uploaded to a gallery with the same name as the folder they are contained in.
# All folders below the Photo Directory path and the images they contain will be uploaded to SmugMug
# Folders that end in _ are ignored, so if you don't want to sync a folder with SmugMug, just add an underscore at the end
#
# Copyright 2008 Shell Tools, LLC

#Region User Defined Variables

$ApiKey = 'uVUvCbXP3f6MgO9wIRJn21YCIgEidVly'
$EmailAddress = '[SmugMug Email]'
$Password = '[SmugMug Password]'
$PhotoDirectory = '[Path To Photos]'
$filesToInclude = @('*.jpg','*.png','*.tif','*.cr2')
$worldSearchable = 1
$smugSearchable = 1

# Professional Accounts Only
$watermark=0
$watermarkId=0

#Email Variables
$smtpServer = '[SMTP Server]'
$smtpUser = '[SMTP User]'
$smtpPassword = '[SMTP Password]'
$smtpFrom = 'PowerSmug@shelltools.net'

#EndRegion

#Region Global Variables

$baseUrl = 'http://api.smugmug.com/hack/rest/1.2.0/'
$userAgent = 'PowerSmug v1.0'
$logFile = 'PowerSmug.log'
$script:SessionId = $null
$script:startStringState = $false
$script:valueState = $false
$script:arrayState = $false
$script:saveArrayState = $false
$script:datFileDirty = $false
$script:datFile = @()
$script:albumList = $null
$script:imageList = $null

#EndRegion

#region Helper Functions

function SendEmail([string] $to, [string] $subject, [string] $msg)
{
    $smtpMail = new-Object System.Net.Mail.SmtpClient $smtpServer
    $smtpMail.DeliveryMethod = [System.Net.Mail.SmtpDeliveryMethod]'Network'
    $smtpMail.Credentials = new-Object System.Net.NetworkCredential $smtpUser, $smtpPassword

    $smtpMail.Send($smtpFrom, $to, $subject, $msg)
}

function Get-MD5([System.IO.FileInfo] $file = $(Throw 'Usage: Get-MD5 [System.IO.FileInfo]'))
{
    # This Get-MD5 function sourced from:
    # http://blogs.msdn.com/powershell/archive/2006/04/25/583225.aspx
    $stream = $null;
    $cryptoServiceProvider = [System.Security.Cryptography.MD5CryptoServiceProvider];
    $hashAlgorithm = new-object $cryptoServiceProvider
    $stream = $file.OpenRead();
    $hashByteArray = $hashAlgorithm.ComputeHash($stream);
    $stream.Close();

    ## We have to be sure that we close the file stream if any exceptions are thrown.
    trap
    {
        if ($stream -ne $null) { $stream.Close(); }
        break;
    }

    # Convert the MD5 hash to Hex
    $hashByteArray | foreach { $result += $_.ToString("X2") }

    return $result
}

function SendWebRequest([string]$method, $queryParams, $ssl = $false)
{
    $url = $baseUrl
    if ($ssl -eq $true) {
        $url = $url.Replace("http", "https")
    }

    $url += "?method=$method"

    foreach ($key in $queryParams.Keys) {
        $url += "&$key=" + $queryParams[$key]
    }

    $wc = New-Object Net.WebClient

    $wc.Headers.Add("user-agent", $userAgent)
    [xml]$webResult = $wc.DownloadString($url)

    CheckResponseForError $webResult

    return $webResult.rsp
}

# Adds image information to our data file
function AddFile ([System.IO.FileInfo]$file, $smugId) { 

    $a = 1 | Select-Object Name, SmugId, LastModifiedTime;
    $a.Name = $file.Name
    $a.SmugId = $smugId
    $a.LastModifiedTime = $file.LastWriteTimeUtc.ToString()

    $script:datFile += $a
#    $script:datFileDirty = $true

    #we are now saving the file after each upload to prevent duplicates when there is a failure
    AppendDataFile $datFilePath $a
}

# writes the data file to the local directory
# each directory will have a data file with information for images contained in it
function SaveDataFile($filePath, $clearFile=$true)
{
    if ($script:datFileDirty -eq $false) { $script:datFile = @(); return }

    [System.IO.File]::Delete($filePath)

    $sortedFile = $script:datFile | sort-Object -property Name
    $sortedFile | Export-Csv $filePath 

    $script:datFileDirty = $false

    # mark the file as hidden
    ls $filePath | foreach { $_.Attributes = $_.Attributes -bor [System.IO.FileAttributes]::Hidden }

    if ($clearFile -eq $true) {
        # clear the variable
        $script:datFile = @()
    }
}

# appends a new row to the data file
function AppendDataFile($filePath, $record)
{
    if (test-Path $datFilePath) {
        $newLine = [System.String]::Format('{0},{1},"{2}"', $a.Name, $a.SmugId, $a.LastModifiedTime)
        Add-Content $filePath $newLine
    }
    else
    {
        $script:datFileDirty = $true
        SaveDataFile $filePath $false
    }
}

# ensure our web request was successful
function CheckResponseForError($xmlResponse)
{
    if ($xmlResponse.rsp.stat -eq 'fail')    {
        throw $webResult.rsp.err.msg
    }
}

#endregion

#region Login/Logout

function Login()
{
    if ($script:SessionId -ne $null) { return }

    $ht = @{APIKey=$ApiKey;EmailAddress=$EmailAddress;Password=$Password}
    $loginResult = SendWebRequest "smugmug.login.withPassword" $ht $true

    if ($loginResult.stat -eq "ok") {
        $script:SessionId = $loginResult.Login.Session.id
    }
    else {
        Throw "Error on login: " + $loginResult.Message
    }
}

function Logout()
{
    if ($script:SessionId -eq $null) { return }

    $ht = @{SessionID=$script:SessionId}
    $logoutResult = SendWebRequest "smugmug.logout" $ht
}

#endregion

#region Images

# this method is only needed if we cannot find the PowerSmug.dat file.
# preventing us from uploading duplicate images
function GetImage($name, $album)
{
    Login 

    $image = $script:imageList.Images | Where-Object { $_.FileName -eq $name }
    if ($image -ne $null) { return $image }

    # we are using heavy because we need the file name
    $ht = @{SessionID=$script:SessionId;AlbumID=$album.id;Heavy=1;AlbumKey=$album.Key}
    [xml]$script:imageList = SendWebRequest "smugmug.images.get" $ht

    return $script:imageList.Images.Image | Where-Object { $_.FileName -eq $name }
}

function UploadFile($file, $albumName)
{
    $album = GetAlbum $albumName
    # $image = GetImage $file.Name $album    
    # if ($image -ne $null) { return $image.id }

    $url = "http://upload.smugmug.com/" + $file.Name

    $wc = New-Object Net.WebClient

    $hash = Get-MD5 $file

    $wc.Headers.Add("user-agent", $userAgent)
    $wc.Headers.Add("ContentMd5", $hash)
    $wc.Headers.Add("X-Smug-FileName", $file.Name)
    $wc.Headers.Add("X-Smug-AlbumID", $album.id)
    $wc.Headers.Add("X-Smug-SessionID", $script:SessionId)
    $wc.Headers.Add("X-Smug-Version", "1.2.0")
    $wc.Headers.Add("X-Smug-ResponseType", "REST")
    $webResult = $wc.UploadFile($url, "PUT", $file.FullName)
    [xml]$webResult = [System.Text.Encoding]::ASCII.GetString($webResult)

    CheckResponseForError $webResult

    return $webResult.rsp.Image.id
}

function UploadExistingFile($file, $id)
{
    Login 

    $url = "http://upload.smugmug.com/" + $file.Name

    $wc = New-Object Net.WebClient

    $hash = Get-MD5 $file

    $wc.Headers.Add("user-agent", $userAgent)
    $wc.Headers.Add("ContentMd5", $hash)
    $wc.Headers.Add("X-Smug-FileName", $file.Name)
    $wc.Headers.Add("X-Smug-ImageID", $id)
    $wc.Headers.Add("X-Smug-SessionID", $script:SessionId)
    $wc.Headers.Add("X-Smug-Version", "1.2.0")
    $wc.Headers.Add("X-Smug-ResponseType", "REST")
    $webResult = $wc.UploadFile($url, "PUT", $file.FullName)

    [xml]$webResult = [System.Text.Encoding]::ASCII.GetString($webResult)

    CheckResponseForError $webResult

    return $webResult.rsp
}

#endregion

#region Album

function GetAlbumList($forceRefresh=$false) {
    Login

    if ($forceRefresh -eq $false) {
        if ($script:albumList -ne $null) { return }
    }

    $ht = @{SessionID=$script:SessionId}
    $script:albumList = SendWebRequest "smugmug.albums.get" $ht
}

function GetAlbum($name)
{
    #before we create an album ensure it doesn't already exist
    GetAlbumList

    $album = $script:albumList.Albums.Album | Where-Object { $_.Title -eq $name }
    if ($album -ne $null) { return $album } 

    Write-Host "Creating album: $name"
    $ht = @{SessionID=$script:SessionId;Title=$name;CategoryID=0;Public=0;
    X2Larges=0;X3Larges=0;Originals=0;Watermarking=$watermark;
    WatermarkID=$watermarkId;WorldSearchable=$worldSearchable;SmugSearchable=$smugSearchable}
    $result = SendWebRequest "smugmug.albums.create" $ht

    # be sure we refresh the album list after creation
    GetAlbumList $true

    return $result.Album
}

#endregion

#region Process File

function ProcessFile([System.IO.FileInfo]$file, $albumName)
{
    $photoObject = $script:datFile | Where-Object { $_.Name -eq $file.Name }

    if ($photoObject -ne $null) {
        if ($photoObject.LastModifiedTime -ne $file.LastWriteTimeUtc.ToString()) {
            # file has been modified, so re-upload the file
            write-Host "Updating existing file: " $file.FullName
            UploadExistingFile $file $photoObject.SmugId
            $photoObject.LastModifiedTime = $file.LastWriteTimeUtc.ToString()

            # mark the dat file as dirty so it will be saved after processing this folder
            $script:datFileDirty = $true
        }
    }
    else {
        #file doesn't exist in local file, upload to SmugMug
        write-Host "Uploading new file: " $file.FullName
        $id = UploadFile $file $albumName
        AddFile $file $id
    }
}

#endregion

#region Main Script

# this section will look through all sub-directories of $PhotoDirectory and upload the images to SmugMug
Get-ChildItem -recurse $PhotoDirectory | Where-Object { $_.Attributes -band [System.IO.FileAttributes]::Directory } | foreach {
    # don't process folders that end in _
    if ($_.FullName.EndsWith("_") -eq $false) {
        $datFilePath = $_.FullName + "\PowerSmug.dat"
        if (test-Path $datFilePath) {
            # casting as array to ensure we have an array returned
            [array]$script:datFile = import-Csv $datFilePath
        }

        $albumName = $_.FullName.Remove(0, $PhotoDirectory.Length).Trim('\')

        $path = $_.FullName + "\*"
        foreach ($file in get-ChildItem $path -include $filesToInclude) {
            ProcessFile $file $albumName
        }
        SaveDataFile $datFilePath
        $script:imageList = $null
    }
}

Logout

$date = Get-Date
Write-Host "Script Completed: $date"

trap [Exception] {
        $date = Get-Date
        $Msg = $date.ToString() + " ; " + $_.Exception.GetType().FullName + " ; " + $_.Exception.Message
        Add-Content $logFile $Msg
        SendEmail $EmailAddress "PowerSmug Error" $Msg
        break
    }

#endregion

—–

Posted in Powershell, pscom | No Comments »

PowerShell Analyzer Refresh for PSV2 + CTP3 advanced function features.

January 8th, 2009 by Karl

Though we don’t have intentions to carry developing PowerShell Analyzer much in the future, there are a number of improvements in my personal fork, and we want to make sure that it keeps its shelf life by updating it for PowerShell V2. Surprisingly we are still getting hundreds of downloads a day so we want to make sure that those who prefer PSA can still keep using it and also take advantage of the features I use day in and day out. We’ll probably release some new builds within the next couple of weeks, but will post some screenshots and maybe videos until then. We hope that will minimal effort keep PSA the best free PowerShell tool. However if want a tool that is definitely worth paying for check out PowerShell Plus at its new home at Idera – http://www.idera.com/Products/PowerShell/

So here is a screenshot of PowerShell Analyzer running with PowerShell V2 CTP3. The new features are all related to the help features of advanced Functions.

  • Region support for multiline comments <# #>
  • Syntax Coloring for help documenting keywords (i.e.  .DESCRIPTION )
  • Code Completion for help documenting keywords.
  • Rich Rendering of advanced function help from get-help in HTML (any advanced function that is in the RunSpace)

1712842

So there. you go. However the help rendering is only in our really old 3 year old Help rendering engine. If you like it wait for our HelpFusion app which will be separate and be able to be used independently or from any PowerShell host. Some of you have seen it, but the rest of you will have to wait until we finish rewriting it for WPF.

Karl

Posted in Powershell, Powershell Analyzer, pscom | 2 Comments »

This is your Admin life. You HAVE to script PowerShell

January 6th, 2009 by Karl

So i was listening to that Dust Brother’s Tyler Durden song from fight club, and PowerShell lyrics started jumping into my head. We’ll most were fleeting before i could capture them, but i did come up with something at least tacky, and fun to some. No offense to anybody. Anyway here is the original song. Listen to it once to get the picture, then a second time while reading my lyrics. Here is a link to the original lyrics.


This is your Admin Life

And you open the door and you step inside
We’re inside our servers

Now imagine that that Blue Screen is a white ball of healing light
That’s right, that exception itself is a white ball of healing light

I don’t think so

This is your job , Good to the last cpu cycle.
It doesn’t get any better than this.
This is your job and its ending one click at a time.

This isn’t your favourite tech conference. This isn’t no geek class.
Where you are now, you can’t even imagine what the bottom will be like
Only after disaster, will your server need resurrected.
Its only after you’ve lost everything that you’ll learn to script anything.
Nothing is static, everything is Dynamic
Without no agile script, it’s all falling apart.

This is your job.
(Without PowerShell)
It doesn’t get any better than this.
This is your job
And its ending one click at a time.

You are not a beautiful and unique engineer.
You are the same decaying GUI based admin  as everybody else.
We are all part of the same time consuming life draining Slavehood
We are the all cringing,ever working info-saviours of the world

You are not your dollarstore tech certification.
You are not your Antivirus failure.
You are not your dumbed down GUI management tools.

You are not your HR employee primary key
You are not your Active Directory login.
You are not your CIO’s latest tech fad.
You are not your hungover 70′s unix shell script.

You have to Code PowerShell.
You have to Code PowerShell.

You have to realize that someday GUI admins will be unemployed
Until you know that, you are useless.

I say never let me be GUI dependant
I say may I never be content.
I say deliver me from MMC console ripoffs.
I say deliver me from VBscript.
I say deliver me from misunderestimating linux zealots.
I say you have to PowerShell
I saw grow, and let the scripts run where they may

This is your job.
(Without PowerShell)
It doesn’t get any better than this.
This is your job
And its ending one click at a time.

You have to Code PowerShell
You have to Code PowerShell

I want you to script me as hard as you can.
I want you to script me as hard as you can.

Welcome to #powershell Club. If this is your first night, you have to code.

Enjoy – Karl

Posted in Powershell, pscom | 7 Comments »

PowerShell Analyzer like execution hotkeys for PS CTP3 ISE.

January 3rd, 2009 by Karl

PowerShell CTP3 ISE – Integrated Scripting environment has inherited many ideas and features from PowerShell analyzer including multiple runspaces,editors, a smaller immediate input area and output pane, however it doesn’t have the output visualizers of PSA nor the super fast RTS like execution control of PSA.

However Microsoft in their wisdom has made ISE rather extensible through the $PSISE variable, and many people already have added some very cool functionality to ISE through these.

When I first demo’d what was then MSH analyzer to Microsoft back in the first few months of 2006, the feature that seemed to stand out the most to the team was the ability to select an area of code and just run that. Thankfully that level of execution control is now in ISE as F6, but I wanted more, so i’m going to share with you a script that build a few months ago to add a couple of features.

F7 run the current physical line.

this basically will run the line where the caret current is at.

Real Time Strategy like control.. CTRL 1 , CTRL 2 etc

This here allows you to use comments to create regions, then EXECUTE those regions with a simple hotkey. I use this extensively. Often i am working on building a function, so I edit the function, press Ctrl 1 to apply the function, then if that was successful, press Ctrl 2 , then maybe Ctrl 3 to run some tests to make sure my changes to the function are what i am expecting.

This gives me a great AGILITY , putting what Jeffery Snover calls the Admin Development Model , but which is really REPL(Repeat Evaluate, Print , Loop ) rediscovered, on agile steroids.

function invoke-caretline
{
invoke-expression $([Regex]::Split($psISE.CurrentOpenedFile.Editor.text,"`r`n" )[$psISE.CurrentOpenedFile.Editor.caretline-1])
}
$psISE.CustomMenu.Submenus.Add("Run single line", {invoke-caretline} ,  'f7')
function invoke-region([int] $num)
{
$ed = $psISE.CurrentOpenedFile.Editor
$lines = [Regex]::Split($ed.text,"`r`n" )
$foundfirst = -1
$foundlast = -1
for($count = 0;$count -le $lines.length-1;$count++)
 {
   if ($lines[$count].startswith("#region") -and $lines[$count].contains("@$num"))
   { $foundfirst = $count;break}
 }
 if($foundfirst -gt -1)
 {
 for ($count = $foundfirst; $count -le $lines.length-1;$count++)
    {
    if ($lines[$count].startswith("#endregion") )
   { $foundlast = $count;break}
    } 

 if ($foundlast -gt -1)
   {
     $torun = ""
     $lines[$foundfirst..$foundlast] | % { $torun+=$_ + "`r`n"}
     invoke-expression $torun
   }
 } 

}
 $psISE.CustomMenu.Submenus.Add("run region 1", {invoke-region 1 },  'ctrl+1')
 $psISE.CustomMenu.Submenus.Add("run region 2", {invoke-region 2 },  'ctrl+2')
 $psISE.CustomMenu.Submenus.Add("run region 3", {invoke-region 3 },  'ctrl+3')
 $psISE.CustomMenu.Submenus.Add("run region 4", {invoke-region 4 },  'ctrl+4')
 $psISE.CustomMenu.Submenus.Add("run region 5", {invoke-region 5 },  'ctrl+5') 

Script @ PoshCode: View Script | Download

Sometime I’ll wrap all this up into a module, and add other PowerShell Analyzer-like functionality such as running the current PARAGRAPH. So often in an earlier PSA, and in SQL Query Analyzer, i’m highlighting again and again the SAME paragraph query and running it over and over again. Being able to just run the current paragraph saves that time.

Technorati Tags: ,,,

Posted in PSV2, Powershell, pscom | 6 Comments »

Help us decide which PowerShell tool to release next.

December 19th, 2008 by Karl

Help us decide which PowerShell tool to release next.

SURVEY: http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&hl=en

Taking an app from an internal application to a shrink-wrap ready for
the masses state is a lot of work, and updating/supporting/marketting
a product even more so. So after the huge sucess of PowerShell Plus
which is now safe in Idera’s hands we need your help to decide what we
are going to release next. We plan to release some free projects, even
some opensource apps, but will likely look at productizing a project
so we can continue to feed our families. Please take the time to take
our survey

—–
As many of you know, PowerShell Plus has been a great success and is
now developed and sold by Idera, and we’ve made PowerShell Analyzer
100% free!. Despite PowerShell Analyzer not having much active
development done for almost 2 years, surprisingly it is still very
popular with a large user base. Based on your feedback and the
following thoughts we need to decide where to invest our development
time, and which internal prototypes to bring to the community.
•       We have invested a lot into PowerShell Plus, from vision and
incubation to a mature product and we don’t want to compete in the
marketplace directly with PowerShell Plus.
•       PowerShell editors are now a generic commodity. In addition to
the awesome PowerShell plus. There are many free “good enough”
solutions, including some open source ones, Microsoft’s upcoming
Graphical PowerShell Integrated Scripting Environment and some other
“lower common denominator” solutions that are still free.
•       We have created and continue to innovate PowerShell technology
that can live just as well outside an editor product as in one.

There are many questions on here. Feel free to not answer them all,
it’s the top questions that are most important to us, but the more you
fill in, the happier you’ll make us.

SURVEY: http://spreadsheets.google.com/viewform?key=pgTpVBomNgDwUA9uQNRKAbw&hl=en

-Karl

Posted in Powershell, Powershell Analyzer, Powershell Plus, Shell Tools, pscom | No Comments »

PowerShell Analyzer now 100% free.

October 2nd, 2008 by Karl

With the phenomenal success of PowerShell Plus and subsequent transfer to Idera, PowerShell Analyzer is now 100% free. You can read more and get it from our recently updated website – http://www.shelltools.net . In coming weeks we are going to do some surveys to help decide where we want to go as a company with PowerShell IDEs.

Sincerely,

Karl

Posted in Powershell, Powershell Analyzer, Shell Tools, pscom | 2 Comments »

« Previous Entries