Write your own Powershell modules
Hi there, in this blog post I want to share some details about a project I work from time to time on. In the past I wrote several scripts and in this scripts I used the same functions. But sometimes you fix a bug or add a new functionally for your functions. In this case you have e.g. 10 scripts with the same function but with different versions of your code.
To get rid of this stuff I had the idea to create my own powershell modules. If you want to use my powershell modules you can just clone/download my Github Repository (https://github.com/marcohorstmann/psscripts/)
In the next sections I will explain how I structured my scripts/functions and how you can adapt it to your needs.
The script which uses the modules
In the template subfolder you will find a template.ps1 file. For your own script I would recommend that you copy the template folder and rename it and the template.ps1 file. With this you have a good basis. This script starts first with a documentation block:
<# .SYNOPSIS Short description what this script is used for .DESCRIPTION Explain in detail what this script do. This block can be of cause multiline as well. .PARAMETER LogFile You can set your own path for log file from this script. Default filename is "C:\ProgramData\template.log" .Example How to run this script with an example .\template.ps1 -parameter1 "\\homelab\dfs" .Notes Version: 1.0 Author: Marco Horstmann (firstname.lastname@example.org) Creation Date: 15 October 2021 Purpose/Change: Initial Release .LINK https://github.com/marcohorstmann/psscripts .LINK https://horstmann.in #>
This is a standardized documentation block for powershell. This will be used e.g. for Powershell Help. Please modify it to explain other people or your future self what does this script to. This helped me a lot.
If you want to allow that your script accepts parameter you have a parameter block:
Param( <# This is a sample parameter you can use to pass commandline parameters to this script [Parameter(Mandatory=$True)] [string]$VBRJobName, #> [Parameter(Mandatory=$False)] [string]$global:Log=$("C:\log\" + $MyInvocation.MyCommand.Name + ".log") )
Important is to keep the parameter “$global:Log”. This Log parameter will be used for logging informations. The mho-common module will check it’s existence and will terminate the script if it wasn’t found.
Now it’s time to load the modules.
# # GLOBAL MODULE IMPORT # # Change current Powershell path to script location Split-Path -Parent $PSCommandPath | Set-Location #Import Logging Module Import-Module ..\include\mho-common\mho-common.psm1 -ErrorAction stop Import-Module ..\include\mho-veeam\mho-veeam.psm1 -ErrorAction stop Import-Module ..\include\mho-netapp\mho-netapp.psm1 -ErrorAction stop Import-Module ..\include\mho-microsoft\mho-microsoft.psm1 -ErrorAction stop Import-Module ..\include\mho-vmware\mho-vmware.psm1 -ErrorAction stop # # GOBAL MODULE IMPORT END #
You are maybe asking why I’ve created per module an own subfolder. This is an requirement of powershell modules.
When the modules are loaded you can find out which functions are available. All my functions have “MHO” in the noun. You can list all functions by running the following command.
PS G:\psscripts\template> get-command -noun MHO* CommandType Name Version Source ----------- ---- ------- ------ Function Add-MHOIpListToNetAppExportPolicy 0.0 mho-netapp Function Add-MHONetAppSnapshot 0.0 mho-netapp Function Add-MHOVbrJobSessionLogEvent 0.0 mho-veeam Function Connect-MHONetAppSVM 0.0 mho-netapp Function Find-MHOADCredentials 0.0 mho-microsoft Function Get-MHODfsFolder 0.0 mho-microsoft Function Get-MHOINT64-toIP 0.0 mho-common Function Get-MHOIP-toINT64 0.0 mho-common Function Get-MHONetAppSVMShares 0.0 mho-netapp Function Get-MHONetAppVolumeInfo 0.0 mho-netapp Function Get-MHOReparsePointDetails 0.0 mho-microsoft Function Get-MHOSmbShares 0.0 mho-microsoft Function Get-MHOTimeStamp 0.0 mho-common Function Get-MHOVBRAgentPolicyBackupsSize 0.0 mho-veeam Function Get-MHOVbrJobNameFromPID 0.0 mho-veeam Function Get-MHOVbrJobSessionFromPID 0.0 mho-veeam Function Get-MHOVeeamProxyIp 0.0 mho-veeam Function Import-MHOADManagementModule 0.0 mho-microsoft Function Import-MHOAWSModule 0.0 mho-common Function Import-MHODfsManagementModule 0.0 mho-microsoft Function Import-MHONetAppOntapModule 0.0 mho-netapp Function Import-MHOVeeamBackupModule 0.0 mho-veeam Function Import-MHOVMwareModule 0.0 mho-vmware Function Remove-MHONetAppSnapshot 0.0 mho-netapp Function Rename-MHONetAppSnapshot 0.0 mho-netapp Function Start-MHOLog 0.0 mho-common Function Write-MHOLog 0.0 mho-common
You can get help for some functions by using this example command.
PS G:\psscripts\template> Get-Help Get-MHOTimeStamp NAME Get-MHOTimeStamp SYNOPSIS This function is used by other function to get the current timestamp as a string for using it e.g. in Write-MHOLog SYNTAX Get-MHOTimeStamp [<CommonParameters>] DESCRIPTION RELATED LINKS Online Version: https://github.com/marcohorstmann/psscripts REMARKS To see the examples, type: "get-help Get-MHOTimeStamp -examples". For more information, type: "get-help Get-MHOTimeStamp -detailed". For technical information, type: "get-help Get-MHOTimeStamp -full". For online help, type: "get-help Get-MHOTimeStamp -online"
I’m not done with implementing help for all functions. Hopefully later all functions will have documentation/help.
After loading the functions we can create a new log file for this script run:
# Create a new Log Start-MHOLog
Now we will load the vendor specific modules. If e.g. NetApp modules are not available it will be automatically installed and progress will be logged to the log file. Or the import command for Veeam modules will take care about loading the V10 or V11 modules.
# Load Veeam Backup Module Import-MHOVeeamBackupModule # Load NetApp Ontap Module Import-MHONetAppOntapModule #Load/Install AD Management Module Import-MHOADManagementModule #Load/Install DfS Management Module Import-MHODfsManagementModule # Laden des VMware Moduls Import-MHOVMwareModule
As last code example of this post I want to show you how you can write a message to a log file. It is just one command.
Write-MHOLog -Info "This is the text which will be logged to the log file" -Status Error
I hope you can use my idea to improve your powershell scripts. In my next post I will use this as well to build another cool solution.