Reputation: 18186
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
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
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
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