One of the problems with writing advanced functions is that new PowerShell users think that they don’t do anything. Frankly, I couldn’t figure out a way to get a notification to work, so I reached out to the sponsor for the Charlotte PowerShell User Group, Microsoft PFE Brian Wilhite. Brian sent me some code which I incorporated into the following snippet:
### Dot Source Reminder Begins ### $ScriptPath= $MyInvocation.MyCommand.Definition.ToString() $fn = $MyInvocation.MyCommand.Name.Replace(".ps1","") if (($host.Name).Contains("ISE")){ Write-host "`n`nYou have loaded the advanced function `"$fn`"" -F Green " Use `"Get-Help`" for information and usage, Ex: PS C:\> Get-Help $fn -detailed`n`n" }ELSE{ if ($MyInvocation.InvocationName -ne '.') { Write-Host "`n`nThis advanced function must be dot sourced to run.`n" -F Green " Load example:`n PS C:\> . `"$ScriptPath`n After loading, use `"Get-Help`" for information and usage, Ex: PS C:\> Get-Help $fn -detailed`n`n" #Pause if launched from shell with "Run with PowerShell" if (([Environment]::GetCommandLineArgs()) -match '&'){pause} } } ### Dot Source Reminder Ends ###
If you expect to have the end-user save the function with code calling it at the bottom of the script, try this version which won’t prompt if there is added text at the bottom:
### Dot Source Reminder Begins ### $ScriptPath= $MyInvocation.MyCommand.Definition.ToString() #you can hard code name of function as $fn #$fn = "Verb-Noun" #Presumew function name is same as script Name $fn = $MyInvocation.MyCommand.Name.Replace(".ps1","") $ScriptTxt = Get-Content $ScriptPath $MoreTxt = [regex]::Split($ScriptTxt,'Reminder Ends ###')[2] if ($MoreTxt.Length -lt $fn.Length){ if (($host.Name).Contains("ISE")){ Write-host "`nYou have loaded the advanced function `"$fn`"" -F Green "`tUse `"Get-Help`" for information and usage, Ex:`n`tPS C:\> Get-Help $fn -detailed`n" }ELSE{ if ($MyInvocation.InvocationName -ne '.') { Write-Host "`nThis advanced function must be dot sourced to run.`n" -F Green "Load example:`n`tPS C:\> . `"$ScriptPath`"`n After loading, use `"Get-Help`" for information and usage, Ex: PS C:\> Get-Help $fn -detailed`n" #Pause if launched from shell with "Run with PowerShell" if (([Environment]::GetCommandLineArgs()) -match '&'){pause} } } } ### Dot Source Reminder Ends ###
Put either bit of code at the bottom of any advanced function. If the script runs inside the ISE, you will get something like this:
You have loaded the advanced function "Get-DownTime" Use "Get-Help" for information and usage, Ex: PS C:\> Get-Help Get-DownTime -detailed
If you run it inside the PowerShell console you will see:
This advanced function must be dot sourced. Load example: PS C:\> . "C:\scripts\Get-DownTime.ps1" Use "Get-Help" for information for information and usage, Ex: PS C:\> Get-Help Get-DownTime -detailed
If you use the shell menu option to Run with PowerShell, it adds a pause so the script does not close. Note that the colors are not rendered properly in the example text — the first line has green text, following lines display with default colors.
Update: if the code above doesn’t pause when you use “Run with PowerShell” from the shell context menu, replace if (([Environment]::GetCommandLineArgs()) -match ‘&’){pause} with if ([regex]::IsMatch([Environment]::GetCommandLineArgs(), ‘powershell_ise’) -eq $false){Pause}. For more on this see this post.