Wednesday, November 25, 2009

In this post I will show you a very simple example of how advanced functions in PowerShell 2.0 can be used to declared your own cmdlets. If you want to run these script samples you will need to run PowerShell as an Administrator when executing set-name and join-workgroup.

Joining a workgroup:

$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$sysInfo.JoinDomainOrWorkgroup( "Bradley" )

Changing the computer name

Another useful example is changing the name of the computer, to do this issue the following command, but remember you must execute this command while in a PowerShell session that has Administrative privileges and you will be required to reboot the computer before these changes take effect (Restart-Computer can do this for you):

$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$sysInfo.Rename("FORSETI")

For completeness and fun I'll now show you how you can take these simple lines of script and create your own cmdlets so that you will have the cmdlets Get-ComputerName, Set-ComputerName, Get-Workgroup and Join-Workgroup at your disposal.

Get-ComputerName

This cmdlet just returns the value held in the environment variable COMPUTERNAME, I'm providing this cmdlet just to have consistency in getting and setting the name of a computer. If you wish to run this script on PowerShell 1.0 simply remove the block comment, this has been included to illustrate how you may document you cmdlets.

function Get-ComputerName
{
    <#
    .SYNOPSIS
        Gets the name of the computer
    .DESCRIPTION
        Returns a string containing the name of the computer
    .NOTES
        File Name: ComputerName.psm1
        Aurthor: Alan Bradley
        Requires: PowerShell 2.0
    .LINK
        http://www.gangleri.net
    .EXAMPLE
        Get-ComputerName
        
    #>
    process 
    {
        $Env:COMPUTERNAME
    }
}

Set-ComputerName

Not much more complicated than the Get-ComputerName cmdlet but this one accepts a parameter that will be the new name of the computer, if ts successfully changes the name of the computer it will prompt the user to reboot the machine so that the change can be applied. I have provided a switch parameter called 'AutoReboot' that when provided will automatically reboot the machine when the name has successfully been changed.

function Set-ComputerName
{
    <#
    .SYNOPSIS
        Sets the name of the computer
    .DESCRIPTION
        Uses WMI to set the name of the computer, if the name is successfully changed the user will be prompted to reboot and apply the changes
    .NOTES
        File Name: ComputerName.psm1
        Aurthor: Alan Bradley
        Requires: PowerShell 2.0
    .LINK
        http://www.gangleri.net
    .EXAMPLE
        Set-ComputerName -Name "{New name for computer}"
    .EXAMPLE
        Set-ComputerName "{New name for computer}"
    .EXAMPLE
        Set-ComputerName -Name "{New name for computer}" -AutoReboot
    .EXAMPLE
        Set-ComputerName "{New name for computer}" -AutoReboot
    .PARAMETER Name
        The new name that the computer will be known by
    #>
    param(
        [Parameter(Position=0, Mandatory=$true,ParameterSetName="Name")]
        [string]$Name,
        
        [Switch]$AutoReboot
    )
    
    process 
    {
        $sysInfo = Get-WmiObject -Class Win32_ComputerSystem
        $result = $sysInfo.Rename($Name)
    
        switch($result.ReturnValue)
        {        
            0 
            { 
                Write-Host -ForegroundColor Green "Success"
                
                if($AutoReboot -eq $false)
                {                    
                    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
                        "Reboots the machine."
                        
                    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
                        "Does not reboot the machine, you will manually have to reboot this machine for changes to take effect."
                        
                    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)    
    
                    
                    $ShouldReboot = $Host.UI.PromptForChoice("Reboot machine", `
                        "You must reboot for change to take effect. Do you want to reboot now?", $options, 0)
                }
                
                if($ShouldReboot -eq 0 -or $AutoReboot -eq $true)
                {
                    Restart-Computer
                }
            }
            5 { Write-Host -ForegroundColor Red "This cmdlet must be execute with administrative privileges" }            
            default { Write-Host -ForegroundColor Red "Error" }
        }
        
    }
}

Get-Workgroup

Similarly cmdlets can be created for changing the workgroup and domain settings. Here is the cmdlet that can be used to get the workgroup name. Again this can be adapted for PowerShell 1.0 by removing the block comments.

function Get-Workgroup
{
    <#
    .SYNOPSIS
        Get the Workgroup name that the computer currently belongs to
    .DESCRIPTION
        This cmdlet returns the name of the Workgroup that the computer
        currently belongs to.
    .LINK
        http://www.gangleri.net
    .Example
        Get-Workgroup
    #>
    process
    {
        (Get-WmiObject -Class Win32_ComputerSystem).Workgroup
    }    
}

Join-Workgroup

Joining a Workgroup can be achieved with the following cmdlet. This cmdlet uses some of the new advanced binding abilities added to PowerShell 2.0 for parameters.

function Join-Workgroup
{
    <#
    .SYNOPSIS
        Joins the specified Windows work group
    .DESCRIPTION
        This cmdlet allows you to specify the name of a Windows Workgroup
        that you would like to join the computer to. You will need to reboot
        for these changes to take effect so the cmdlet will prompt you to do
        this, alternatively you can use the -AutoReboot switch as this will
        automatically reboot the machine so that the changes are applied.
    .LINK
        http://www.gangleri.net
    .Example
        Join-Workgroup "WorkgroupName"
    .Example
        Join-Workgroup "WorkgroupName" -AutoReboot
    .EXAMPLE
        Join-Workgroup -Workgroup "WorkgroupName"
    .EXAMPLE
        Join-Workgroup -Workgroup "WorkgroupName" -AutoReboot
    .PARAMETER Workgroup
        The name of the Windows Workgroup you wish to join
    .PARAMETER AutoReboot
        If supplied this instructs the cmdlet to automatically 
        reboot the computer so that the changes can take effect
    #>
    
    param(
        [Parameter(Position=0, Mandatory=$true,ParameterSetName="Workgroup")]
        [string]$Workgroup,
        
        [Switch]$AutoReboot
    )

    process
    {
        $sysInfo = Get-WmiObject -Class Win32_ComputerSystem
        $result =  $sysInfo.JoinDomainOrWorkgroup( $Workgroup )
        
        switch($result.ReturnValue)
        {            
            0 
            { 
                Write-Host -ForegroundColor Green "Success"
                
                if($AutoReboot -eq $false)
                {                    
                    $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", `
                        "Reboots the machine."
                        
                    $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", `
                        "Does not reboot the machine, you will manually have to reboot this machine for changes to take effect."
                        
                    $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)    
    
                    
                    $ShouldReboot = $Host.UI.PromptForChoice("Reboot machine", `
                        "You must reboot for change to take effect. Do you want to reboot now?", $options, 0)
                }
                
                if($ShouldReboot -eq 0 -or $AutoReboot -eq $true)
                {
                    Restart-Computer
                }
            }
            
            5 { Write-Host -ForegroundColor Red "This cmdlet must be execute with administrative privileges" }
            
            default { Write-Host -ForegroundColor Red "Error" }
        }
    }
}

Changing the Domain

Working with domains is similar to working with workgroups, you will use the JoinDomainOrWorkgroup method only you need to specify additional arguments for the user name and password. The values one and two are important. One means join the domain and two means create the account.

$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$sysInfo.JoinDomainOrWorkgroup( "Bradley", "password", "Bradley\Admin", 1, 2 )

If you fancy a small challenge you could try writing your own cmdlet 'Join-Domain' give me a shout if you need any help. Also how the return codes are processed could be wrapped up in a function I've just duplicated code here to make it easy for people to copy/paste these examples and play with them. I'll be posting a sort example of turning these scripts into PowerShell 2.0 modules that you can easily distribute to others.

Although the add-computer cmdlet in PowerShell 2.0 can achieve this same functionality I still think these are good examples of developing your own cmdlets using PowerShell 2.0 advanced functions as they are not complicated and allow you to focus on the nuts and bolts of advanced functions. Next I'll walk you through packaging these as modules so that you will then be in a position to easily redistribute your cmdlets to others.

posted on Wednesday, November 25, 2009 11:48:12 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Thursday, November 05, 2009

I've had a few questions regarding uninstalling Windows PowerShell 1.0 on XP to make way for PowerShell 20. It's actually quiet simple although not immediately obvious. PowerShell doesn't show up under Add/Remove programs as it's counted as a Windows update so follow these steps it you want to uninstall it.

    1. Click Start -> Run
    2. Type appwiz.cpl and press enter
    3. Windows PowerShell will not show up in the list of programs as it is counted as a windows update, you must click the tick box "Show updates"
    4. Scroll down and look for "Windows XP - Software Updates"
    5. Underneath the Windows XP -Software updates entry is a list of all updates that have been applied to you machine scroll through the list and you will find an entry call "Windows PowerShell(TM) 1.0"
    6. Click the "Remove" button to begin uninstalling PowerShell 1.0

 Screen showing Add Remove PowerShell

 

You can find more details on this in the Microsoft knowledgebase at:  http://support.microsoft.com/kb/926139

posted on Thursday, November 05, 2009 8:33:13 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [2]
 Saturday, October 17, 2009

If you want to learn more about PowerShell Dr. Tobias Weltner has published Mastering PowerShell and is giving it away as a free download from PowerShell.com. This is well worth getting, just look at the table of contents and you'll agree.

  1. The PowerShell Console
  2. Interactive PowerShell
  3. Variables
  4. Arrays and Hashtables
  5. The PowerShell Pipeline
  6. Using Objects
  7. Conditions
  8. Loops
  9. Functions
  10. Scripts
  11. Finding and Avoiding Errors
  12. Command Discovery and Scriptblocks
  13. Text and Regular Expressions
  14. XML
  15. The File System
  16. The Registry
  17. Processes, Services, Event Logs
  18. Windows Management Instrumentation
  19. User Management
  20. Your Own Cmdlets and Extensions

I'm a convert to PowerShell for awhile now and use PowerShell script as often as I can to automate tasks that I just couldn't bear doing time and time again. Recently I've used it along with PSake to generate build scripts and to write other scripts that make setting up the developer environment a breeze. Trust me you'll never write a batch file again. This would also be a technology I'd recommend learning as it'll probably start showing up on hot skill lists soon.

Get the eBook here: http://powershell.com/cs/blogs/ebook/

posted on Saturday, October 17, 2009 1:54:49 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Saturday, September 26, 2009

A problem that I often have is trying to get the UNC path for a mapped drive so that I can pass it to somebody or that they can pass the UNC path to me. My ideal solution would be to execute a command passing the drive letter as an argument and having the UNC path copied to the clipboard so that I can then paste the UNC path in an email or instant message, so I wrote the following script using PowerShell and the PowerShell community extensions (PSCX).

If you don't already have them installed install the following:

Then save my script to a folder on your computer and run it as follows

.\DrivePath z

Where 'z' is the drive letter for the mapped drive, the UNC path will then be on your clipboard and you can then paste it wherever you like.

param(
    [Parameter(position=0, Mandatory=$true)]
    [string] $Drive = "Z:"
)

# ensure the supplied param ends with ':' 
$Drive = $Drive.ToUpper().ToCharArray()[0] + ":"

$logicalDisk = Gwmi Win32_LogicalDisk -filter "DriveType = 4 AND DeviceID = '$Drive'"

out-clipboard $logicalDisk.ProviderName

 

Download script: DrivePath.zip

posted on Saturday, September 26, 2009 10:27:29 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Tuesday, June 09, 2009

Included with the RC release of Windows 7 is PowerShell version 2 and a new editor called 'PowerShell ISE' (Integrated Scripting Environment).  Previously when I've been writing PowerShell scripts I've used PowerGUI as my script editor of choice so once I'd upgrade to Windows 7 I was keen to put the new PowerShell ISE to the test.

When I first started PowerShell ISE I get the standard screen as shown in the screen shot. I see there is a debug menu and with a script file open I can see there is reasonable support for syntax highlighting. PowerShell ISE

It's a relatively simple and clean interface, with a tabbed editor that allows you to easily move between scripts that you're editing and the toolbar isn't overly cluttered. However I did notice one thing slightly odd a slider control in the bottom right of the editor's window. This allows you to easily increase on decrease the size of the font used in the editor, not something I can see myself using that often as I'm normally set configuration like this up once in my development environment such as Visual Studio or Netbeans.

PowerShell ISE large text

One other point I noticed very early was the use of the Ctrl+W shortcut, in most web browsers this closes a tab and in PowerGUI it also closes the current editor window, however in PowerShell ISE the Ctrl+T and Ctrl+W key relate to output panel. My personal preference would have been for these to work with the script editor window.

The next thing I was keen to try was debugging, being well used to working with Visual Studio I tried to double click in the line number where I wanted the breakpoint, this didn't work but fortunately the keyboard shortcut F9, a small point but I'm always happy when there is some consistency between editors especially when they come from the same company. When debugging the shortcut keys F10 and F11 are also consistent with Visual Studio's debugging.

When debugging you can mouse over a variable name to see the value that has been assigned. However PowerGUI gives slightly more information as it will also tell you the type of the variable.

Debugging in PowerShell ISE Debuggin in PowerGui

 

 

 

One thing I did notice is that PowerShell ISE will break at the following line and allow you to step over it and wait at the next line, when I step over the second line PowerShell ISE will then display an error in the output window, however PowerGUI will report the error once I step over the first line and doesn't stop at the second line, to stop at the second line I needed to set a specific breakpoint.

lines of script

Another useful feature in PowerShell ISE is the ability to issue debug commands at the command window while debugging. For example just type the name of a variable and it's value will be displayed in the output window. PowerShell ISE DBG example

Other useful features are the ability to view the call stack using the keyboard shortcut Ctrl+Shift+D, and highlighting sshot-7a cmdlet and pressing F1 to get the help form that particular cmdlet. 

However despite the very good support for debugging PowerShell Scripts I prefer the intellisense offered by PowerGUI. PowerShell ISE does offer tab completion in the editor for cmdlet names however I prefer the Ctrl+Space option available in PowerGUI as this matches what I'm used to given that Visual Studio is mostly my day to day environment. I do appreciate that Tab completion option would be more familiar to System Admins. PowerGUI intellisense

But PowerShell ISE still has one trick up it's sleeve with it's programmability. PowerShell ISE has it's own object model thus allowing you to extend it with your own PowerShell script. You can add the script to the ISE profile and this will then be persisted between sessions. Note that this is a different profile than PowerShell and you can create the necessary file by typing the following command into the ISE command prompt:

if (!(test-path $profile )) {new-item -type file -path $profile -force}

Once the profile script has been created you can open it and start changing settings some settings. In Visual Studio I like to use the font 'Consolas' so these two lines of code will set ISE to use the font I like and at my preferred size when the editor starts.

$psise.options.fontname="Consolas"
$psise.options.fontsize=15

This is a very simple example of what's possible using the profile script to customize ISE but more complex customization is possible such as adding new menu items. If you put the following script into your profile and restart ISE you'll see a new entry on the menu bar called 'Add-ons', under this you will find an option 'Say Hi' click this and the famous 'Hello World!' message will be displayed in you editor pane.

function Get-Message
{
    $psise.CurrentPowerShellTab.Files[0].Editor.InsertText("Hello World!")
}
$null = $psise.CurrentPowerShellTab.AddOnsMenu.Submenus.Add("Say Hi", {Get-Message}, $null)

 

If you want to find out what members are available on the $psise object just issue '$psise | Get-Member' at the command window in ISE.

So which is best? Out of the box PowerGUI suits me the best due to the similarity with Visual Studio however I found the debugger better in PowerShell ISE. Also I'll be giving serious consideration to PowerShell ISE's programmability and experimenting with this to see how far I can push it, I'll post any interesting extensions I create.

posted on Tuesday, June 09, 2009 8:18:58 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Tuesday, April 21, 2009
I’m going to show you how easy it is to build a Windows PowerShell Cmdlet using Visual Studio 2008, C# and my PowerShell Cmdlet templates available on CodePlex.
  1. Download my Windows PowerShell Cmdlet templates from CodePlex

  2. Run the VSI installer to install the project and item templates

  3. Open Visual Studio 2008 and select File->New->Project



  4. From the New Project dialog select  the ‘PowerShellCmdlet’ template



  5. Now right click on the project and select ‘Add New Item’. This will show the ‘Add New Item’ dialog. You can see that there are class templates for PSCmdlets, Cmdlets, SnapIns and XML helper files. For now select the Cmdlet template.



  6. The ProcessRecord method performs the actual processing for the Cmdlet, in this example we will just call the WriteObject method to display the ‘Hello World’ message.

    using System.Management.Automation;
    
    namespace HelloPowerShell
    {
        [Cmdlet(VerbsCommon.Get, "HelloCmdlet")]
        public class HelloCmdlet : Cmdlet
        {
            protected override void ProcessRecord()
            {
                WriteObject("Hello World!");
            }
        }
    }
    


  7. Again right click on the project and select add new item, this time select the ‘PowerShellCmdlet Help XML’. The template will automatically prefix ‘.dll-help.xml’ therefore you should just type ‘Get-Hello’ as the name.

    <?xml version="1.0" encoding="utf-8" ?>
    <helpItems xmlns="http://msh" schema="maml">
      <command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" 
    xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10"
    xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10"> <command:details> <command:name> hellocmdlet </command:name> <maml:description> <maml:para>hellocmdlet</maml:para> </maml:description> <maml:copyright> <maml:para>Copyright</maml:para> </maml:copyright> <command:verb></command:verb> <command:noun></command:noun> </command:details> <maml:description> <maml:para> hellocmdlet description </maml:para> </maml:description> </command:command> </helpItems>

  8. Now add another new item and select the ‘PowerShellCmdlet SnapIn’ template. Call this ‘HelloSnapIn.cs’

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Management.Automation;
    using System.Management.Automation.Runspaces;
    
    namespace HelloPowerShell
    {
        [RunInstaller(true)]
        public class HelloSnapIn : CustomPSSnapIn
        {
            private Collection<CmdletConfigurationEntry> _cmdlets;
    
            /// <summary>
            /// Gets description of powershell snap-in.
            /// </summary>
            public override string Description
            {
                get { return "A Description of HelloCmdlet"; }
            }
    
            /// <summary>
            /// Gets name of power shell snap-in
            /// </summary>
            public override string Name
            {
                get { return "HelloCmdlet"; }
            }
    
            /// <summary>
            /// Gets name of the vendor
            /// </summary>
            public override string Vendor
            {
                get { return ""; }
            }
    
            public override Collection<CmdletConfigurationEntry> Cmdlets
            {
                get
                {
                    if (null == _cmdlets)
                    {
                        _cmdlets = new Collection<CmdletConfigurationEntry>();
                        _cmdlets.Add(new CmdletConfigurationEntry
                          ("Get-HelloCmdlet", typeof(HelloCmdlet), "Get-HelloCmdlet.dll-Help.xml"));
                    }
                    return _cmdlets;
                }
            }
    
        }
    }
    


  9. By default the SnapIn template fills out some sample information using MyCmdlet as the name simply change this to refer to Get-HelloCmdlet.

  10. You can build the project and get a dll

  11. Now start Windows PowerShell and run with administrator privileges as you will be installing a Cmdlet.

  12. If you are using a 64-bit version of windows issue the command:
    Set-Alias installutil C:\Windows\Microsoft.NET\Framework64\v2.0.50727\InstallUtil.exe
    If you have a 32-bit version of windows issues the command:
    Set-Alias installutil C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe

  13. Now install your Cmdlet with the command:
    installutil HelloPowerShell.dll

  14. You can verify that the Cmdlet has been installed with the command:
    Get-PSSnapin -Registered

  15. Add the snap-in to your shell with:
    Add-PSSnapin HelloCmdlet

  16. You can run the Cmdlet with the command Get-HelloCmdlet and you should see the message “Hello World!”

For more details on installing and register your Cmdlet refer to: http://msdn.microsoft.com/en-us/library/ms714644(VS.85).aspx

posted on Tuesday, April 21, 2009 2:34:20 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Sunday, April 19, 2009
http://www.codeplex.com I've just created a project on CodePlex for a set of Visual Studio 2008 project and item templates to aid in the development of Windows PowerShell Cmdlets. Check them out here!

I'm planning on refining these templates based upon user feedback and will add support for Visual Basic in future. The templates are released under Apache License 2.0 and a Subversion repository has been set up so please feel free to add some feedback or contribute.

Image credit: MSMVPS.com


posted on Sunday, April 19, 2009 11:16:28 AM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Tuesday, February 24, 2009
When reading "The Productive Programmer" one of the things that really impressed me was the ability to  write an ant build script using groovy. Currently make Java days seem to be more and more on ice as I travel further down the road of .NET I wanted this ability when generating build scripts for my .Net  
solutions. Searching the web lead me to psake. This is a project that allows you to use PowerShell syntax in your build scripts.

Psake was started by James Kovacs and is in the early stages of development. You can download the source  (a single Ps1 file) from Google code using the following address svn url:

    http://psake.googlecode.com/svn/trunk/ psake-read-only

On windows I would recommend Tortoise SVN. Once you checkout the project you will get have a single ps1 file called "psake.ps1" and two folders "examples" and "images". The examples folder contains some useful examples on using psake.

The basic usage of psake is:

psake buildFile

Where buildFile is a PowerShell script file that contains the build tasks. If no build file is specified  
psake will assume default.ps1. For additional information on using psake from the command line use psake -help.

Psake is a wrapper around PowerShell that adds functionality specific for creating a build script. Because  it has been built on top of PowerShell anything you can do in PowerShell is available to you in psake. One  other useful point to mention is that psake will automatically add the correct version of the .NET  framework to its path thus calling framework tools like msbuild.exe, csc.exe or vbc.exe extremely straight forward.

An example build script that is included with the download is:

properties {
  $testMessage = 'Executed Test!'
  $compileMessage = 'Executed Compile!'
  $cleanMessage = 'Executed Clean!'
}

task default -depends Test

task Test -depends Compile, Clean {
  Write-Host $testMessage
}

task Compile -depends Clean {
  Write-Host $compileMessage
}

task Clean {
  Write-Host $cleanMessage
}



The default entry point for your script is the default task defined as:

task default

You then specify what tasks the default task depends on using the '-depends' switch. So in the build  script above the default task depends on the Test task the test task depends on the Compile and Clean tasks, therefore unsurprisingly the clean task will execute followed by the compile and finally the script  in the Test task will execute.


Here is s simple example that builds a Hello World solution:


task default -depends Build

task Build
-depends Clean{
  msbuild "C:\Users\Alan\Code\PowerShell\psake\HelloWorld\HelloWorld.sln"
}

task Clean {
  msbuild
"C:\Users\Alan\Code\PowerShell\psake\HelloWorld\HelloWorld.sln" /t:clean
}



This is a very simple script that cleans and builds a solution using MsBuild. The screenshot below shows the output from executing the script, you can see that it reports the task that it is executing and displays a green success message. If the task fails a red error message is displayed detailing why the task failed.




Although this is still a work in progress I think this project definitely has potential as script such as  that shown above can be much cleaner and hence easier to read than XML therefore this is a project I would hotly tip for the future.

Some useful resources, I recommend the podcast from PowerScripting as this is an interview with James Kovacs where he really explains the pros of psake:


posted on Tuesday, February 24, 2009 9:18:45 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Tuesday, February 17, 2009
With the advent of Windows PowerShell automating tasks in windows should now be a sinch for a .NET developer as PowerShell's scripting language is relatively easy to a C# programmer to pickup (trust me I've come down the path). One of the things I have a lot of is MP3 files from my extensive music collection and various podcats that I listen to, so I needed a way to manipulate these tags for example change some details such as adding missing information or even move the files into my music folderr structure.

A library that allowed me to do this easily was TagLib Sharp. It's avaliable from Novell and will work with .NET and Mono.

Because this is a .NET assembly you are free to use it in your C#, Visual Basic .NET. To use the library with any of thse languages simply add the assembly as a reference to your project and add the appropriate using or imports statement to the top of the class file that will use the library. However as PowerShell is my new best friend I'll show you how to use the library with PowerShell.

To use any assembly in your PowerShell script you can use the Assembly class in the System.Reflection namespace. The Assembly classes has the static LoadFile method that allows you to specify a location to load a dll from.

[Reflection.Assembly]::LoadFile("C:\Users\Alan\Code\PowerShell\MyScripts\taglib-sharp-dotnet20.dll")


Once you have imported the assembly as shown above you can begin to use it to modify settings on you media files. For example the line below will create a File object that represents the specified physical media file.

$media = [TagLib.File]::Create( "$filePath" )

Once this has been done you simply access the various tags using $media.Tag.XXX. The script below will set the Title and Track information.

$media.Tag.Title = $matches["title"]
$media.Tag.Track = $trackNum.ToString()

Once you have set the tags to the values you want you save the changes by calling the Save method on the media file object.

$media.Save()

One thing I did notice when using this library was that it failed to set the tags if they previously had no value so to get around this I manually set the tags to a character for sting values and 1 for numberic values suchas year and track number.




posted on Tuesday, February 17, 2009 3:16:51 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Sunday, February 15, 2009
This is one of the books from Manning with the cool covers that I like. This book has been written by Bruce Payette one of the designers of PowerShell. Because of this the book offers in-depth information on many aspects of PowerShell.  The book is split into two sections. Part one focuses on the basics, it covers using PowerShell at the command line and writing and run your own scripts. I read the nine chapters in this section from start to finish and was please to find lots of working and easy to follow code examples which I could play with and easily refer back to as I wrote my own scripts. I found this section greatly enhanced my knowledge of PowerShell in a short space of time, I would put this down to a good balance between verbose text and script examples to experiment with and if you are like me and learn beat by doing this book will suit you. The second section covered more advanced topics such as:
  1. Processing text files and XML
  2. .NET and WinForms
  3. Windows objects: COM and WMI
  4. Security

These were also detailed chapters with good examples however to date I have gotten more use from chapters 10 and 11 this is no fault  with the book it’s more of a reflection on what I’ve been working with recently. Since taking the time to sit down with this book I have become very keen on PowerShell especially having seen and used the scripting tools available on Linux and UNIX.

I found the book well structured and importantly for me it contains lots of script examples. Previously I had tried to learn PowerShell simply from various web sites however lack of discipline kept getting in the way. With the book I was able to discipline myself better and managed to work through this book in just over one week. Now I’m able to write my own scripts and when I’ve needed to I’ve found it very easy to refer back to the book. The back cover says that this is a book for sysadmins and developers, I would agree with this and would recommend this book for people with previous scripting of programming experience if you don’t have these then a more basic beginners book may allow you to make more progress.

The books web site: http://www.manning.com/payette/

posted on Sunday, February 15, 2009 6:18:46 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Thursday, February 12, 2009
If you are writing any scripts for PowerShell I'd recommend looking at PowerGUI Script Editor. It's a free comunity project that has some really nice features you now expect when writting code such as intelli-sense, syntax highlighting and the ability to debug your script.

The overall aim of the project is to create a GUI for Windows PowerShell where you can manipulate objects in PowerShell by pointing and clicking. For example there is bundled functionality to list all process running on the current system invoke actions on these processes such as stopping the process. Personally I just use the script editor to edit my scripts and as I have customized my PowerShell as described in a previous post, it easy for me to then execute these scripts as I need.




posted on Thursday, February 12, 2009 2:26:33 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Friday, February 06, 2009
Windows PowerShell is Microsoft's latest command line and scripting language. It's a major move forward from the days on MS-DOS Batch files and gives Windows a scripting environment more in keeping with the likes of the Bash Shell on Linux. Needless to say I like PowerShell and there are enough people out there already singing it's prasies what I want to highlight is the ability to customize the PowerShell environment for yourself.

Those of you comming from Unix or Linux will possibly have at one point encountered the '.bash_profile'. This was a hidden file in the root of your home directory and allowed you to customize various settings suchas adding environment variables. This was extremely useful and I can recall adding various JAR files to a classpath environment variable in a previous life. So when I came over to PowerShell and started writting my own scripts I wanted to may life easy for myself. Typing C:\users\alan\code\scripts is just too much like hard word even with tab complition. Wouldn't it be nice to just type 'cd $MyScripts'? Well it is and with tab completion of environment variables all I need to type is 'cd $mys' the tab key takes care of the rest.

PowerSehll has a hierarchl structure for profiles which allows profiles to be specified once for all users or for an individual user. It's simply a matter of knowing where on the hard drive to store the 'ps1' script. Your options are as follows:
  • %windir%\system32\WindowsPowerShell\v1.0\profile.ps1
  • %windir%\system32\WindowsPowerShell\v1.0\ Microsoft.PowerShell_profile.ps1
  • %UserProfile%\My Documents\WindowsPowerShell\profile.ps1
  • %UserProfile%\My Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1

Those profiles stored under the %windir% will effect all users whereas profiles stored under the %UserProfile% will effect only that user.

Ok so now we can look at a bit of PowerShell script to create the profile and begin customizing it.


test-path $profile
new-item -path $profile -itemtype file -force
notepad $profile

Note if you wanted to create a profile for all users replace the '-path' argument on the new-item cmdlet call with one of the paths listed above.

Now that you have a profile you can start customizing it, one of the most common things I've stored in my profile in the past has been environment variables. To do this with PowerShell simply use the Set-Variable cmdlet as shown below where I create a new variable called 'MyScripts' which will point to 'C:\Users\Alan\Code\PowerShell\MyScripts'


Set-Variable -Name MyScripts -Value "C:\Users\Alan\Code\PowerShell\MyScripts"

posted on Friday, February 06, 2009 4:14:24 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]
 Thursday, February 05, 2009
If you've used the Command Prompt Here PowerToy in the past you'll definitely want this ability when you make the move to PowerShell. You have two options.

  1. Customize the ini file for the command prompt here PowerToy
  2. Download an already had version here from Scott Hansleman

posted on Thursday, February 05, 2009 4:45:34 PM (GMT Standard Time, UTC+00:00)  #    Add Comment | Comments [0]