Archives for the Month of March, 2009

More Tied Variables in PowerShell

Ibrahim just posted something to the PowerShell blog about how to create tied variables in PowerShell. If you extend this approach with script blocks, you have a very powerful dynamic scripting technique.

PS C:\temp> cd \temp
PS C:\temp> New-ScriptVariable.ps1 GLOBAL:lee { $myTestVariable } { $GLOBAL:myTestVariable = 2 * $args[0] }
PS C:\temp> $lee
PS C:\temp> $lee = 10
PS C:\temp> $lee
20
PS C:\temp> New-ScriptVariable.ps1 GLOBAL:today { (Get-Date).DayOfWeek }
PS C:\temp> $today
Wednesday
PS C:\temp> New-ScriptVariable.ps1 GLOBAL:random -Get { Get-Random } -Set { Get-Random -SetSeed $args[0] }
PS C:\temp> $random
1740776676
PS C:\temp> $random
1507521897
PS C:\temp> $random = 10
PS C:\temp> $random
1613858733
PS C:\temp> $random = 10
PS C:\temp> $random
1613858733

He alluded to it in the post – here is the full text of the script:

(Edit 05/17: Updated to make the getters more like PowerShell pipelines: return a single object, or collection of PSObject)

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
## New-ScriptVariable.ps1
param($name, [ScriptBlock] $getter, [ScriptBlock] $setter)

Add-Type @"
using System;
using System.Collections.ObjectModel;
using System.Management.Automation;

namespace Lee.Holmes
{
    public class PSScriptVariable : PSVariable
    {
        public PSScriptVariable(string name,
            ScriptBlock scriptGetter, ScriptBlock scriptSetter)
            : base(name, null, ScopedItemOptions.AllScope)
        {
            getter = scriptGetter;
            setter = scriptSetter;
        }
        private ScriptBlock getter;
        private ScriptBlock setter;

        public override object Value
        {
            get
            {
                if(getter != null)
                {
                    Collection<PSObject> results = getter.Invoke();
                    if(results.Count == 1)
                    {
                        return results[0];
                    }
                    else
                    {
                        PSObject[] returnResults = new PSObject[results.Count];
                        results.CopyTo(returnResults, 0);
                        return returnResults;
                    }
                }
                else { return null; }
            }
            set
            {
                if(setter != null) { setter.Invoke(value); }
            }
        }
    }
}
"@

if(Test-Path variable:\$name)
{
    Remove-Item variable:\$name -Force
}
$executioncontext.SessionState.PSVariable.Set(
    (New-Object Lee.Holmes.PSScriptVariable $name,$getter,$setter))

 

Want to Influence the PowerShell Cookbook V2?

We've started working on the next edition of the PowerShell Cookbook, and one obvious goal is to improve on the first version.

As the first version has been in print, I've taken notes on where people get confused with certain recipes. I've taken notes on what I felt were content gaps, and taken the feedback from reviews on Amazon.com and random blogs. Reviews on Amazon are GOLD for authors. They help readers form educated opinions, and provide helpful feedback about the book itself. If you want to thank the author of a book you like, write a review on Amazon.

The second edition of the PowerShell Cookbook continues in the same tradition as the first. Topical, real-world solutions to everyday problems. Packed with an appendix of reference material that matters. It will continue to be a purposefully distinct approach from PowerShell in Action.

With that, here's your chance to influence the next edition. What did you find too basic? Too advanced? Missing altogether? Were there any recurring issues with the approach or content?

Another question we're pondering is the unique value that the printed edition brings to the table. Much of the content in the PowerShell Cookbook was pre-published to this blog, newsgroups, or other channels. Many of the topics it addresses can be found through internet searches and forums. Many copies are floating around on Bit Torrent. Given all of that, why did you still purchase the printed version?

I know -- a lot of questions, very few answers! Let 'er rip.