- PSJumpStart
The PowerShell PSJumpStart module is a multi-purpose module targeted to create an environment for running, creating and editing PowerShell scripts. The environment is highly customizable for different usages and the module comes with some simple but usefull start-up functions. Search the PowerShell Gallery or the internet to add functionallity or override included functions. See Other repositories section for inspiration.
A folder with template files are included to provide a set of files to jump start PowerShell programming.
-
One of the most useful features is the setting files solution. You can use either
.json
or.dfp
files to populate variables and/or the standard PowerShell feature$PSDefaultParameterValues
. The files are read in a preset order so you may have different defaults for different scenarios. -
The package contains a
Functions
folder and an empty customizableLocalLib
folder for local usage found in the module folder. Functions in the local folder will override any existing functions in theFunctions
folder, so you can copy a function and improve it for local usage. TheLocalLib
feature also extends to the current running scripts folder. So you can have the same function name in different versions at each script foldersLocalLib
location. The correct set of function files will be loaded by theImport-Module
call. -
Any DLL-files found in any
LocalLib
folder will be loaded by anAdd-Type
call. -
Any
.Ps1Xml
files found in anyTypeData
folder will be loaded according to the same loading order as theLocalLib
process. -
Any
Format.Ps1Xml
files found in anyFormats
folder will be loaded according to the same loading order as theLocalLib
process. -
The
Msg
-function provides a generic handling of showing/logging information. It can be pre-configured using.json
or.dfp
files as described below. -
The function
Add-ScriptHeader
will add a comment-based help PowerShell header from theparam()
content andUpdate-ScriptHeader
checks and fixes any missing parameter(s) in existing headers. Use-WhatIf
option to see suggested header(s). -
Another noteworthy function is the
Get-ModuleHelp
-function for getting module information. Try it with or without arguments. -
A feature for cached
PSCredentials
for named systems is included. RunGet-Help Get-AccessCredential
for details. -
A set of template files is provided to jump start script creation. The templates comes in two main flavors, PSJumpStart and Basic. The basic templates does not load the module and may act as stand alone scripts while the PSJumpStart templates is using the included module. All templates are
Get-Help
enabled. TheTemplate
folder also holds theScriptSigner.ps1
file that will sign your files with an existing code signing certificate (or create a new one). -
A template
CMD
file is also provided for calling PowerShell scripts withStdOut
andStdErr
capturing. The primary intended use is launching PS-scripts from Task Scheduler as unhandled errors cannot be traced otherwise. It is a generic template and may be used to launch any PowerShell script. -
The
Samples
folder in the module folder contains test/sample scripts for reference. -
One sample
ps1xml
file is included for extending theHashTable
object type with methods forReplace
andAppendValue
. -
A script signing feature is included that is not dependent on the module. The script signing feature will use an existing certificate if found or create a new one at run-time.
-
The
_Tests_
folder has a set of Pester tests.
Because we are system administrators that just want to get going with PowerShell using basic supporting functions for common use.
Because we want a jump start for writing a script with Get-Help
support by using included templates.
Because we want to be able to copy a script from one environment to another without the need to change them making code signing easier (or less of a hassle). Default input arguments are read from settings files.
Because we want to choose how output (messages, verbose and errors) are handled for each site and/or environment without rewriting the scripts. Log to windows eventlog, a log file or only to StdOut
?
Because we want to be able to set default parameters depending on user, domain or script but be able to override these default parameters by using the script arguments.
Because we would like to have local PS functions to expand/replace the PSJumpStart base features without risking override by PSJumpStart updates.
Have a look in the PSJumpStart.json
or PSJumpStart.dfp
file (in the module Functions
folder) using a text editor. Those are the least significant default settings. Use them to set your preferred configurations (see $PSDefaultParameterValues
for details).
The load order of setting files is described below, but let's have an example; A PowerShell file is located on a test-server and a prod-server. The file issues an Invoke-RestMethod
but you want each file to use different URL:s accoring to environment. The url is part of input parameters as $RestApiUrl
, but you want default value depending on script location. If the servers are located in different domains the solution would be to create domain named json
files. If the servers are sitting in the same domain the solution is made by creating server named json
files.
These files may be used to set default values for script input arguments as well as function call arguments. The syntax for setting default values for standard functions follow the $PSDefaultParameterValues
"Function-Name:Argument-Name":"value/code"
To populate standard input argument values to a .ps1
you remove the function name part of the line above
"Argument-Name":"value/code"
So if you want $PSpids
to contain currently running PowerShell sessions, you may use "PSpids": "(Get-Process -Name \"PowerShell\" | Select-Object -ExpandProperty Id)"
in a json
file.
Call the function Get-GlobalDefaultsFromJsonFiles
to get content for $PSDefaultParameterValues
. Copy the GetLocalDefaultsFromFiles
function from the template file PSJumpStartStdTemplateWithArguments.ps1
. Or just use the template as starting point.
The .dfp
flawor works the same waay as the .json
files. The support is provided for legacy reasons. The syntax for setting default values for standard functions looks like this
Function-Name:Argument-Name=value/code
To use a dfp
file as a repository for standard input argument values to a .ps1
you remove the function name part of the line above
Argument-Name=value/code
So if you are using a site name argument in several scripts ,[string]$SiteName
, you may create a logon domain named dfp
file with content SiteName="www.whatever.com"
Call the function Get-GlobalDefaultsFromDfpFiles
to get content for $PSDefaultParameterValues
and the local function GetLocalDefaultsFromDfpFiles
to set local script variables. Or simply use the template file PSJumpStartStdTemplateWithArgumentsDfp.ps1
as a starting point.
The json
or dfp
files are read in a specific order by Get-SettingFiles
where the most significant setting will rule over the lower order settings. The order of loading is:
- Provided arguments will always override any default file settings.
- User logon ID (
[System.Security.Principal.WindowsIdentity]::getCurrent()
) file name in script folder. - Computer file name (
$Env:COMPUTERNAME
) in script folder. - Logon provider file name (domain or local machine) in script folder.
- Script name file in script folder.
- Computer file name (
$Env:COMPUTERNAME
) in script folder. - Logon provider file name (domain or local machine) in PSJumpStart module folder.
- Any other loaded module name in the PSJumpStart module
Functions
subfolder (for instance anActiveDirectory.json
file). - The
PSJumpStart.json
file in the moduleFunctions
subfolder.
It is also possible to call Get-SettingFiles
to retreive a string array of file names with any given suffix in the above order.
The json
or dfp
files may also be used to setup the logging environment by setting default variables for the Msg
function. It may write output to log files, event log or output to console only. Please remember to run any PowerShell as Adminstrator the first time to create any custom log name in the event log. The use of the settings files will enable you to set different event log names, but use this carefully as any script registered for a log name cannot write to another event log name without removing the source using Remove-Eventlog
.
During loading of functions the PSJumpStart.psm1
file will load any ps1
function files from the folder LocalLib
in the modules folder. Customized functions will override any PSJumpStart functions. So you may add any local functions to enhance the module.
It is also possible to create a LocalLib
folder in any location containing PSJumpStart enabled ps1
files. This makes it possible to have a set of ps1
files targeted for a specific purpose with their own set of local functions. These functions will of course override any existing functions in the module folders.
The PSJumpStart.psm1
file will use the Add-Type
command to load any .dll
files found in a LocalLib
folder. The load order follow customized funktion loading. For example;
A script is created in C:\MuppetLabb
to read items from a Sharepoint list using CSOM. This requires the dll Microsoft.SharePoint.Client.dll
. This dll file may be placed in the C:\MuppetLabb\LocalLib
folder for exclusive use by scripts in C:\MuppetLabb
or in the PSJumpStart module LocalLib
folder for access by all PSJumpStart scripts. Only the C:\MuppetLabb\LocalLib\Microsoft.SharePoint.Client.dll
will be lodaed for scripts in C:\MuppetLabb
if the dll file is located in both folders.
The problem; If you are calling a function in a loaded module and want to see the results from Write-Verbose
you need to add -Verbose:$VerbosePrefererence
in the arguments for the call. By using json
or dfp
files you may activate debug mode for whatever part you need.
Please note that the global variable $PSDefaultParameterValues
is lost in nested psm1
function calls. So if you call a sub-function from a psm1
function you need to retreive the content of $PSDefaultParameterValues
into the calling psm1
function using $PSDefaultParameterValues = (Get-Variable -Name PSDefaultParameterValues -Scope Global).Value
Edit the PSJumpStart module json
and dfp
files to activate debug mode for ALL scripts, modules and function calls: set "*:Verbose":true
and *:Verbose=$true
in the files. The next execution session will activate verbose mode across the board. This can be done by using a specific user json
and/or dfp
file so only that user will get verbose feedback.
To debug your script as well as get Write-Verbose
printouts from ALL used modules and functions;
- Create a
json
ordfp
file (depending on what the script uses) with the same name as your script. - Put
"*:Verbose":true
or*:Verbose=$true
in it. - Run the script to load
Verbose
mode in current session.
Using the argument -Verbose
when starting the script will set verbose mode for hte script itself, not only the called functions. Add "Verbose":true
or Verbose=$true
to your file if you don't want to user the argument switch.
If you only need to get verbose printout from a specific function you can add "Function-Name:Verbose":true
in any json
file, or Function-Name:Verbose=$true
in any dfp
file.
In the Templates
folder (living in the module folder) is a set of templates. Use Find-PSTemplate
in the PSJumpStart module to list the template files. Copy a template to your preferred working space by using Copy-PSTemplate
.
There is a little stand alone feature in the Templates
folder for script signing. It will search for a valid CodeSigning
capable certificate on the local computer. If not found a new self signed certificate will be created. The found/new certificate is then used to sign single scripts or all scripts in a folder.
This feature is not dependent on the PSJumpStart module.
This module comes with a .cmd
file used for calling its corresponding PowerShell. The runCleanupEmptyGroups.cmd
will launch the CleanupEmptyGroups.ps1
PowerShell script with any provided arguments. The default behaviour of this template is to catch any output from the PowerShell and dump it to a log file in a logs
sub folder. If any unhandled exceptions occur they will be put in a separate ERR_
log file.
The primary use for this is in the Task Scheduler. If you launch a PowerShell script directly from Task Scheduler you will not be able to get the exception data written by the PowerShell script. The .cmd
file will trap and log the information.
The recomendation for Task Scheduled scripts is using a .json
or .dfp
named after the service account running the job. Then you may turn off any other logging method for .ps1
files and let the .cmd
file handle logging to file.
Let's dive in to look at some of the main features in the package.
The local function for json
files is named Get-LocalDefaultVariables
to populate default script arguments. The param($ArgOne)
will be populatated from the line "ArgOne":"This is the default value if the user does not provide a command line value"
in any found json
file. It is possible to use a structural json
file for populating variables.
{
"RestApi":{
"AccessUrl":"https://server/EE",
"AccessCredential":"(Get-AccessCredential -AccessName 'RestApi')",
"UseMethod":"ooolala"
}
}
The value for UseMethod
above is found in the PowerShell variable $RestApi.UseMethod
.
The function Get-LocalDefaultVariables
has two extra arguments. The switch -defineNew
will create local variables for all found variables in json
files, not only existing empty variables (input arguments) in the local script. The other switch is -overWriteExisting
that will reverse the load order making the module json
files override any user provided command arguments or settings.
The corresponding local function GetLocalDefaultsFromDfpFiles
is a local script function for using dfp
files to populate default arguments. But it is missing the extras...
The use of json
or dfp
files separates default parameters from the PowerShell scripts. The files are loaded in a preset order using the Get-SettingsFiles
function where the first encountered setting is used. The Get-GlobalDefaultsFromJsonFiles
function is used for loading json
file content into the PowerShell variable $PSDefaultParameterValues
the corresponding function for dfp
files is of course Get-GlobalDefaultsFromDfpFiles
.
As $PSDefaultParameterValues
may be set for all functions it is possible for Write-Verbose
to present output from directly called functions in modules without adding -Verbose:$VerbosePrefererence
in the calling script.
PLEASE NOTE that the $PSDefaultParameterValues
is NOT inherited into called child module functions. To ensure standard values use in nested module function (psm1
) calls you need to add the command $PSDefaultParameterValues = (Get-Variable -Name PSDefaultParameterValues -Scope Global).Value
in the calling module function (not pretty but it works).
The story behind the Get-CallerPreference
function
More information on the use of $PSDefaultParameterValus
:
The Microsoft Docs Tale
Some practical usage samplings
The unified way of writing output information from calling scripts. There are a number of arguments available when calling this function making it possible to write output to log file as well as windows Eventlog. Use the .json
files framework to set default values for input arguments. This example will write information to a log file (in script folder with same name as script + year and month) AND to the Windows Eventlog PSJumpStart
:
{
"Msg:useFileLog": true,
"Msg:useEventLog": true,
"Msg:logFile": "($(Split-Path -Parent $MyInvocation.PSCommandPath) + '\\' + $(Split-Path -Leaf $MyInvocation.PSCommandPath) + '.' + (Get-Date -Format 'yyyy-MM') + '.Log')",
"Msg:EventLogName": "PSJumpStart"
}
The Msg
-function will write messages using Write-Output
or Write-Error
if it does not write output to a log file or eventlog. This will write messages to the std-out or std-err pipe. As PowerShell does not have a separated function output pipe you need to have this in mind when using Msg
in called functions who returns data. If any logging is enabled (eventlog or file) the Msg
will use Write-Host
to present output. If this is not what you want, just copy the function to a localLib
folder and change it according to current needs.
To use this function from any psm1
(loaded) function or nested functions, you may need to retrieve the global content of $PSDefaultParameterValues
adding the following code line:
$PSDefaultParameterValues = (Get-Variable -Name PSDefaultParameterValues -Scope Global).Value
There are times when you just want to run your admin task PowerShell without typing the password at every run time. And one morning I just got tired of it, so I wrote this function. It is based on the commonly used PSCredential
object and this loaded by Import-Clixml
and saved using Export-Clixml
. If a file is missing the function will call itself with the -renew
option presenting a dialog for getting new credentials. The saved xml
file is protected by both current user and computer context. It is only possible for the correct user to retreive the password in clear text.
So the name of the cashed credential file will be $env:ComputerName + "." + $env:UserName + "$AccessName.xml"
. The AccessName may be used to identify access files for different systems/purposes.
To ensure correct environment the $CallerInvocation
is used as input parameter by some functions in the psm1
file. The input should be $MyInvocation
of the root caller script.
Some words on the PowerShell module environment
The PSJumpStart module will add two methods to the Hashtable
variable type. The Replace
method will add or replace an existing value in a hashtable. The AppendValue
will append new values to any existing data by creating an array of values.
The inspiration for enhancing the Hashtable
object type by using a ps1xml
file
It is possible to use -defineNew
and/or -overWriteExisting
when calling the function Get-LocalDefaultValues
to load all variable definitions in all setting files. The function will normally only add values to existing empty variables (typically defined in the param()
section). The -overWriteExisting
option will turn the tables on the load order making setting files king of data.
The folder Samples
included in this package has some code samples for calling functions in the module. For example SQLqueryTest.ps1
where the local function dumpDBresult
explores the result from calling Invoke-SqlQuery
.
The template folder also include the file Set-PSJumpStartCommandPromtEnvironment.ps1
. This file will create variables according to the current set of json
files with verbose output. This is very useful in some test and/or development scenarios.
Futher down the rabbit hole to Jumstart your PS authoring...
A nice article on the practical use of CustomObjects in PowerShell
Deep dive articles at Microsoft provides a set of articles for usefull information.
There are many very talanted people out there and this is just a few samples found searching for inspirations. You may populate your local environment with whatever you need.
PSScriptTools is a generic library of functions/formats/types focused on enhancing the PowerShell console prompt. The module is installed from Powershell Gallery
PoshFunctions is also a vast collection of functions for use in different scenarios. This is also found at PowerShell Gallery.
ADExportImport is a solution based on this module. The solution exports/imports Active Directory object structure. The LocalLib
folder has specific functions used by the solution.
ServiceAccountHandler is also a solution using the PSJumpStart framework. It handles service account passwords for a set of computers/services.
Please feel free to add an issue for suggest improvements or found issues.