views:

1450

answers:

3

I'm finding myself writing a bunch of related functions dealing with different nouns (clusters, sql servers, servers in general, files, etc.) and put each of these groups of functions in separate files (say cluster_utils.ps1, for example). I want to be able to "import" some of these libraries in my profile and others in my powershell session if I need them. I have written 2 functions that seem to solve the problem, but since I've only been using powershell for a month I thought I'd ask to see if there were any existing "best practice" type scripts I could be using instead.

To use these functions, I dot-source them (in my profile or my session)... for example,

# to load c:\powershellscripts\cluster_utils.ps1 if it isn't already loaded
. require cluster_utils

Here are the functions:

$global:loaded_scripts=@{}
function require([string]$filename){
      if (!$loaded_scripts[$filename]){
           . c:\powershellscripts\$filename.ps1
           $loaded_scripts[$filename]=get-date
     }
}

function reload($filename){
     . c:\powershellscripts\$filename.ps1
     $loaded_scripts[$filename]=get-date
}

Any feedback would be helpful.

+2  A: 

Mike, I think those scripts are awesome. Parceling out your functions into libraries is very useful, but I think your functions to load scripts is very convenient.

The one change I would make would be to make the file location a parameter also. You could set a default value or even use a global variable for that. You don't need to add the ".ps1"

$global:scriptdirectory= 'c:\powershellscripts'
$global:loaded_scripts=@{}
function require(){
      param ([string]$filename, [string]$path=$scriptdirectory)
      if (!$loaded_scripts[$filename]){
           . (Join-Path $path $filename)
           $loaded_scripts[$filename]=get-date
     }
}

function reload(){
     param ([string]$filename, [string]$path=$scriptdirectory)
     . (Join-Path $path $filename)
     $loaded_scripts[$filename]=get-date
}

Nice functions!

Steven Murawski
+2  A: 

Building on Steven's answer answer, another improvement might be to allow loading multiple files at once:

$global:scriptdirectory = 'C:\powershellscripts'
$global:loaded_scripts = @{}

function require {
  param(
    [string[]]$filenames=$(throw 'Please specify scripts to load'),
    [string]$path=$scriptdirectory
  )

  $unloadedFilenames = $filenames | where { -not $loaded_scripts[$_] }
  reload $unloadedFilenames $path
}

function reload {
  param(
    [string[]]$filenames=$(throw 'Please specify scripts to reload'),
    [string]$path=$scriptdirectory
  )

  foreach( $filename in $filenames ) {
    . (Join-Path $path $filename)
    $loaded_scripts[$filename] = Get-Date
  }
}
Emperor XLII
A: 

I think you'll find the "modules" functionality of PowerShell v2 to be very satisfying. Basically takes care of this for you.

Don Jones
My impression is that I'll find a lot of the functionality of v2 to be very satisfying. However, since the release date is so far off, I'm staying away from installing it. I'm trying to implement the good ideas in v1 whenever I can.
Mike Shepard