Mike Shepard
Mike Shepard

Reputation: 18186

Importing "libraries" in powershell

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.

Upvotes: 13

Views: 16997

Answers (3)

Emperor XLII
Emperor XLII

Reputation: 13452

Building on Steven's 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
  }
}

Upvotes: 5

Don Jones
Don Jones

Reputation: 9497

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

Upvotes: 1

Steven Murawski
Steven Murawski

Reputation: 11255

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!

Upvotes: 3

Related Questions