Quick, Dirty, Super-Useful Scripting

Quick, Dirty, Super-Useful Scripting

  • Comments 5

Last weekend I installed the super-awesome W7 Ultimate on all the machines at home.  This weekend I decided to install the XP Virtual mode download.  I started to do this and noticed that it was 500MB.  That is large and is going to take a long time FOR EACH PC I have.  One of the reasons I got the Ultimate SKU is that it has BranchCache.  This is EXACTLY what Branchcache was designed to do.  One PC downloads something and puts it into a distributed cache and then when the other PCs go to download it, they get it from their peers instead of from the internet (given the way my son reacts when my downloads affects the network and  his ability to kill Nazi Zombies, I’m motivated to minimize the usage of the network :-) ).

That sounds great but the Branchcache is not enabled by default so you have to set it up.  I was doing this and it was a pain in the butt so I decided to experiment with a quick and dirty script and I LOVE the results so I thought I would share.

The issue is that they way you configure Branchcache is with NETSH.  The problem with that is that NETSH isn’t remotable.  I was going back and forth between machines trying things out.  I gave myself a dopeslap and I realized what I was doing and established a remote PowerShell session to the machines.  For a while I was doing Enter-PSSession which gives you an interactive session to the remote machine.  That was great but I have more than one machine so I either had to switch machines or have a couple of windows open.  Then I decided I would use Invoke-Command.  I created a remote connection to all the machines and then collected them in a variable $s and used ICM.

PS> $s = GSN
PS> icm $s {netsh branchcache show localcache}

That worked great but it was a little clumsy to work with so I decided to write a quick-n-dirty function to make my life better.

function b { icm $s -ScriptBlock $([scriptblock]::create("netsh branchcache $args "))}

Notice that I’m not using VERB-NOUN.  Why should I?  I’m after FAST (minimal typing) and this is a throw away function.  “B” is perfect.

Notice that I didn’t declare parameters.  Why should I?  I’m going quick.  I need it to work but I don’t need it to be formal.

Notice that I use positional parameters and aliases?  Why not? 

Now what I’m able to do is:

PS> b show localcache
PS> b set service mode=DISTRIBUTED

I realized from the comments that I didn't deliver the punchline.  The WHOLE point was that the command is going to run on ALL the machines!  THAT's the crazy wonderful part of it.

I haven’t got Branchcache working yet but I’m am zooming and having a blast.   We spend a lot of time talking about best practices and formal scripting.  That is all super great and super important but there is NOTHING wrong with quick-n-dirty scripting for adhoc functions.  The fact that we designed it so that you can do both with PowerShell is a source of great pride.


Experiment!  Enjoy!  Engage!

Jeffrey Snover [MSFT]
Distinguished Engineer
Visit the Windows PowerShell Team blog at:    http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:  http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Leave a Comment
  • Please add 5 and 3 and type the answer here:
  • Post
  • You actually can do netsh remotely with psexec.. Just sayin..

    psexec \\machinename cmd.exe



    set service mode=distributed

    exit when your done..

    (I'd use WinRM, but have not figured it out yet)

    Powershell and SysInternals really have made Windows an enterprise product, don't underestimate your contribution to M$.. I'm Not your typical M$ evangelist.. I've been a Slackware linux guy since `94..

    My two favorite microsoft employee's:

    J. Snover

    M. Russinovitch

  • Great info. I'm just getting into this and it's so difficult. Thank you for this post!

  • I love this example.  That core[scriptblock]::create("... $args ...") has all sorts of potential for other similar hacks.

    My favorite quick and dirty functions are:

    ${function:...} = {process{$o=$_;@($args|%{$o.($_)})}}

    function ql {$args}

    function p {

    $names = (ql Name Expression FormatString Width Alignment)

    $spec = @{}

    for($i=0; $i -lt $args.Length; ++$i) { $spec.Add($names[$i], $args[$i]) }



    The first two are inspired by various other sources, the last is my own.  It is used to create the hashtable needed with Select-Object and the Format-* cmdlets.

  • Netsh is remotable (was still using it yesterday).

    netsh -r mycomp or netsh set machine mycomp

    Nice script anyway, thanks for sharing !

  • allthouth netsh -r is indeed remoting netsh, you do need the same components installed locally as those you're trying to remote.

    Otherwise explained: if you want to netsh -r settings concerning a Windows 2008 NPS (radius) server, you need to do it from a server which has NPS installed aswell.

    So therefor the powershell thingy is nice because it does not have this requirement

Page 1 of 1 (5 items)