Windows PowerShell modules present a simple way to organize and package our script so as to make it distributable and reusable.
In this section, we will cover the following topics:
Windows PowerShell can be created dynamically or persisted to our disk. While discussing PowerShell modules, for a moment I thought about the old-style snap-ins in PowerShell version 1.0, which still exist. Yeah! SharePoint still has snap-ins and not modules.
Snap-ins only contain cmdlets and providers, whereas in modules, we can have functions, variables, aliases, and PowerShell drives.
Before we create a module, we need to know what a module should deliver and where it should be placed. Use this code to find the module path:
$env:PSModulePath -split ';'
You will see two different paths, where one is the system location and the other is the user profile location, as follows:
$ENV:WindirSystem32WindowsPowerShellv1.0Modules $ENV:UserProfileDocumentsWindowsPowerShellModules
The folder name and module name should be the same. For example, if you create an ADUserInformation
module, you need to save it under a folder named ADUserInformation
.
Any valid PowerShell code can be made as a script module. You can create a PowerShell script with a bunch of functions and save it as a PSM1 file, and that would be a script module.
Normally, we save the PowerShell script as PS1; if you save it as PSM1, you can't run the code as a script. Instead, we would need to use the Import-Module
cmdlet, load the module to the disk, and make use of the cmdlets. The cmdlets here are nothing but your function name, as shown in the following code:
Function Get-RunningServices { (Get-Service).Where({$_.Status -eq 'Running'}) } Function Get-StoppedServices { (Get-Service).Where({$_.Status -eq 'Stopped'}) } New-Alias -Name grsv -Value Get-RunningServices New-Alias -Name gssv -Value Get-StoppedServices Export-ModuleMember -Function * -Alias *
Now, we will use the Import-Module
command to load the module. Take a look at the following image:
The points marked in the figure are explained in the following list:
The following code will show you the aliases and functions that we will create in the PSM1 file:
Get-Module WindowsService | Select ExportedAliases , ExportedFunctions
Using Windows PowerShell 5.0, we can write a class, save it as PSM1, and explore the objects. In the following example, we can take a look at how this works:
Class Demo { $FirstName $SurName GetInformation($ID) { $result = Get-ADUser -Identity $ID $this.FirstName = $result.GivenName $this.SurName = $result.SurName } }
The preceding code will result as shown in the following image:
A binary module is an assembly file (the DLL file). Inbuilt PowerShell modules are good examples of binary modules. Execute the following code:
Get-Module –Name Microsoft.PowerShell.*
Binary modules are faster and easier to build using a PowerShell reference. We can parameterize, validate the parameters, and perform many such functions in binary modules. A great feature in Visual Studio is that while parameterizing, we can get a syntax highlighter, which makes our job easier and faster.
The following exercise will guide us to creating a binary module. It's simple, and all this does is clear the temp files and the temp IE files. For this, we will create three cmdlets and compile them as DLL.
Perform the following steps to create a binary module:
System.Management.Automation
DLL as a reference. This is available in your system's GAC
assembly folder.Class.cs
.Let's take a look at the usage and explanation:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Management; using System.Management.Automation; using System.IO; namespace Windows_Management { [Cmdlet(VerbsCommon.Clear, "TemporaryInternetFiles")] public class WindowsManagement : PSCmdlet { protected override void ProcessRecord() { //Delete Internet Cache Files and Folders string path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Clearing Temporary Internet Cache Files and Directories....." + path); System.IO.DirectoryInfo folder = new DirectoryInfo(path); foreach (FileInfo files in folder.GetFiles()) { try { files.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } foreach (DirectoryInfo Directory in folder.GetDirectories()) { try { Directory.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } Console.WriteLine("Done Processing!!!"); Console.ResetColor(); } } } namespace clearInternetexplorerHistory { [Cmdlet(VerbsCommon.Clear, "IEHistory")] public class clearInternetexplorerHistory : PSCmdlet { protected override void ProcessRecord() { // base.ProcessRecord(); string path = Environment.GetFolderPath(Environment.SpecialFolder.History); Console.ForegroundColor = ConsoleColor.DarkYellow; Console.WriteLine("Clearing Internet Explorer History....." + path); System.IO.DirectoryInfo folder = new DirectoryInfo(path); foreach (FileInfo files in folder.GetFiles()) { try { files.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } foreach (DirectoryInfo Directory in folder.GetDirectories()) { try { Directory.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } Console.WriteLine("Done Processing!!!"); Console.ResetColor(); } } } namespace UserTemporaryFiles { [Cmdlet(VerbsCommon.Clear, "UserTemporaryFiles")] public class UserTemporaryFiles : PSCmdlet { protected override void ProcessRecord() { //base.ProcessRecord(); string temppath = System.IO.Path.GetTempPath(); System.IO.DirectoryInfo usertemp = new DirectoryInfo(temppath); Console.WriteLine("Clearing Your Profile Temporary Files..." + temppath); foreach (FileInfo tempfiles in usertemp.GetFiles()) { try { tempfiles.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } Console.WriteLine("Done Processing!!!"); foreach (DirectoryInfo tempdirectory in usertemp.GetDirectories()) { try { tempdirectory.Delete(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } } } } }
Import-Module
cmdletClear-TemporaryInternetFiles
clears the temp IE filesClear-IEHistory
clears the IE historyClear-UserTemporaryFiles
clears the user temporary filesA manifest module is nothing but a data file with a PSD1 extension. This file will describe the contents of the module and how the module process works.
The manifest module is used to export an assembly that is installed in the global assembly cache. A manifest module is also required for modules that support the
Updatable Help feature. Updatable Help uses the HelpInfoUri
key in the manifest module to find the help information (HelpInfo XML) file, which contains the location of the updated help files for the module.
A manifest module can be created using PowerShell cmdlets. You can even manually type and save the file as PSD1, but using PowerShell is quicker. In the following example, we will create a manifest module:
$Param = @{ Author = "Chendrayan Venkatesan" CompanyName = "Contoso" ModuleVersion = "1.0" Description = "Module Manifest Demo" PowerShellVersion = "5.0" Path = "C:TempModuleManifestDemo.psd1" } New-ModuleManifest @Param
The preceding code creates a manifest module, as shown in the following image:
The remaining parameter that we missed will be commented in the manifest module. We can manually edit it using any text editor.
A dynamic module is a module that does not persist on the disk but in the memory; so, it will be lost once you close your PowerShell session. This type of modules can be created from the functions and script blocks within the same session, which is useful to developers for a better, object-oriented scripting. It is also useful to administrators at times when they want to execute certain modules on remote computers where they physically exist using PowerShell remoting. Dynamic modules are created using the New-Module
cmdlet and with parameters such as -Function
and –ScriptBlock
, which specify the function and script blocks that are to be included in this module.
In the following example, let's create a dynamic module using the New-Module
cmdlet:
New-Module -ScriptBlock {Function Print {"Dynamic Module Demo!"}; Print}
This creates a dynamic module with the exported Print
cmdlet, as follows:
PS C:> Print Dynamic Module Demo!