Showing posts with label module. Show all posts
Showing posts with label module. Show all posts

Saturday, December 06, 2014

Type Accelerators – And a Module

Over the years, I've written about type accelerators and PowerShell. A type accelerator is simply a synthetic type name that you can create to serve as an alias to another type name. For example, you could use the int16 type to refer to the System.Int16, or guid instead of [system.guid]. Type accelerators are meant to simplify handling of types by IT Pros in PowerShell scripts.

TAs were first introduced in a beta of PowerShell V2, and I posted code that worked (then). However, I have been recently updating my script library blog (http://pshscripts.blogspot.com), I discovered that TAs stopped working that way. After some fun and effort, I've now found hot how they work today, and how you can play with them!

TAs work by just providing you with an alias to a full type name. To some degree, TAs make up for the lack of a Using statement such as in the C# language. Some common TAs in use include [ADSI], [WMI], [String], [regex] and many more.

This week, I have published a new TypeAccelerators modules. This module contains scripts that define 4 TA-related functions:

  • Get-TypeAccelerator– this gets the TAs active in your current PowerShell Session. This function also takes a parameter (AliasRE) which is a regular expression over the type accelerators to return.
  • Measure-TypeAccelerator – this just returns a count of the TAs active.
  • New-TypeAccelerator – this adds a new type accelerator that aliases an existing type
  • Remove-TypeAccelerator – this removes a type accelerator from your current system.

Here's a screen shot of using these TAs

 image

The scripts also create aliases for these functions: GTA, CTA, NTA and RTA as you might imagine. The module also includes an about_ file for help – you get this importing the module!

You can get the module at http://www.reskit.net/powershell/typeacceleratosr.zip. I will also look to publish this module to the new PowerShell V5 Internet module repository (and maybe Chocolatey too if I get time).

A small footnote: this module and the scripts therein are intended to illustrate the concepts around type accelerators. They lack any sort of pipeline friendliness or error handling. So if you decide to make use of the concepts here – make sure you add the production quality aspects to your code, leveraging mine.

Tuesday, January 22, 2013

Improving PowerShell with 3rd party Modules

PowerShell is an awesome product with amazing potential. But as we al know, the product team can not do everything and neither can the various product teams at Microsoft. As has been quite evident since Monad first peeked it’s head outside Redmond, the community can provide a lot of great extra functionality. Some an alternative to MS produced code (e.g. the Quest AD cmdlets), while other add-ons add features not available elsewhere.

These add-ons are typically, at least since V2, wrapped up in a module and the module then published somewhere. Finding these modules can be quite a chore as they are scattered all over the Interweb! The Microsoft Script Gallery project has quite a few add-on modules published in their archives.

Here’s a set of the most popular modules published at the Microsoft Script Centre:

File System Security PowerShell Module 2.1.
Allows a much easier management of permissions on files and folders using PowerShell. Download this module at: http://gallery.technet.microsoft.com/scriptcenter/1abd77a5-9c0b-4a2b-acef-90dbb2b84e85.

Local Account Management Module 2.1
This module allows managing local groups and user accounts, local group membership and some other useful tasks. It is mostly based on the .net classes in System.Dir. Download this module at: http://gallery.technet.microsoft.com/scriptcenter/Local-Account-Management-a777191b

Active Directory Replication PowerShell Module 2.01
Managing Active Directory Sites, Site Links and Subnets very easily with PowerShell. Also checking the Active Directory Replication is easy and richer than repadmin.exe, the cmdlets in this module do return objects and not just text. So no more boring test parsing. Download at: http://gallery.technet.microsoft.com/scriptcenter/780a2272-06f9-4895-827e-9f56bc9272c4

DHCPAlternateConfiguration PowerShell Module
The DHCP Alternate Configuration module is a command line interface for managing the DHCP client alternate configuration as described. Download at: http://gallery.technet.microsoft.com/scriptcenter/DHCPAlternateConfiguration-90e92431

Kerberos Module
The module gives access to the Kerberos ticket cache. It can read and purge tickets of the current logon session. Download from: http://gallery.technet.microsoft.com/scriptcenter/Keberos-Module-3a6ab12a

Windows Update PowerShell Module
The PSWindowsUpdate module helps you manage Windows Update on a computer system running Windows. Whole module contain 9 function to check, download and install updates from PowerShell. Download at: http://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc

Registry Security PowerShell
Allows a much easier management of permissions inside the registry database using PowerShell. Download at: http://gallery.technet.microsoft.com/scriptcenter/ce4c51a1-43df-42df-bbd1-c2ad0249a864

Sunday, January 30, 2011

Creating PSDrives for Modules

In my PowerShell training, I spend time examining modules and how you can use them to manage code and avoid profile bloat. In the (forgive the pun) modules on modules, I do lots of demos where being able to quickly set your location to the personal or system modules folder is useful. One simple way I demonstrate is to create PS drives pointing to the folders. I do this as follows:

# First, create variables pointing to each folder
$mod       = (ls env:psmodulepath).value.split(";")[0]
$sysmod    = (ls env:psmodulepath).value.split(";")[1]

# Now create PsDrives
New-PSDrive -name mod    -root $mod     –PsProvider FileSystem | out-null
New-PSdrive -name sysmod -root $sysmod  –PsProvider FileSystem | out-null

As you can see, I first create variables corresponding to the two built in Profile folders. The PsModulePath environment variable is set to a string holding the names of these folders, delimited by a semi-colon. Once I have the $mod and $sysmod variables, I can call New-PSDrive to create the drives. The last two PowerShell statements do return a value, so to to keep the output to a minimum, I just pipe the results to out-null (although I’ll quickly point out there are other ways to avoid the output!)

Wednesday, June 02, 2010

PowerShell Admin Module – A Follow Up

in a recent blog article I wrote about a new Codeplex project called PowerShell Admin Modules, being developed by super-star MVP Richard Siddaway. I noted two small things I’d noticed about the module. Well today, Richard wrote to say he’d fixed Get-Share to accept wildcards and had changed around the parameters of New-Share to match that of the venerable Net Share.

He also mentions the latest version, 0.2, has a bunch of functions for dealing with binary and hex numbers, which include:

  • ConvertTo-Binary
  • ConvertTo-Decimal
  • ConvertTo-Hex
  • Get-BinaryAND
  • Get-BinaryDifference
  • Get-BinaryOR
  • Get-BinarySum
  • Get-BinaryXOR
  • Get-HexDifference
  • Get-HexSum
  • Test-Binary
  • Test-Hex

This is nice work – although one thought would be to merge the functions of PSAM into the PowerShell Community Extensions.

Tuesday, January 06, 2009

PowerShell Audit Reports – Turning Great Scripts Into a Module

I just read a neat blog post entitled PowerShelling Audit Reports over on the TenBrink Tech blog. This blog post sets out three scripts: GetRecursiveGroupMembership.ps1, Audit-QuickGroup.ps1, and Audit-MultipleGroups.ps1. The second and third make use of the first. They make use of Quests’s AD tools to create CSV file(s) containing details of members in an AD Group.

Scripts to Modules

Dillon (the post’s author) has implemented all three of these as separate PS1 files. Which is so Version 1. :-)!!  As I read through his scripts, I could not escape the felling that a much better approach would be to implement them as a single module with PowerShell V2. So I did! It took a bit more time than I’d hoped, but it helped me to learn a bit more about modules in PowerShell V2.

Creating a Module

I first created a module file (audit.psm1) which contained the three functions Dillon created. These were slightly modified to be functions rather than script files, but the resulting module is essentially identical to the original. I also created a module manifest, which describes the module, and indicates the functions the module should expose to the user once the module is imported. I felt the first function was a helper function so the module only exports two functions not all three.Of course, I could be wrong, but it did make an interesting challenge – just exporting two of the three functions using a manifest.

Here’s the PSM1 Module itself:

  1. # 
  2. Write-Host "Importing Module Audit.psm1" 
  3. function Get-RecursiveGroupMembership { 
  4. <# 
  5. .SYNOPSIS 
  6.     Gets membership of a group.   
  7. .DESCRIPTION 
  8.     Uses recursion to handle nested groups 
  9. .NOTES 
  10.     File Name  : Audit.psm1 
  11.     Author     : Dillon (@tealshark on Twitter) 
  12.     Updated by : Thomas Lee tfl@psp.co.uk 
  13.     Requires   : PowerShell V2 CTP3 
  14.     This is a helper function and not exported by the module. 
  15. .LINK 
  16.     http://www.pshscripts.blogspot.com 
  17.     http://tenbrink.us/index.php/2009/01/03/powershelling-audit-reports/ 
  18. .PARAMETER DistinguishedName 
  19.     This paramater is the DN of the group you want to expand 
  20. .PARAMETER AddOtherTypes 
  21.     This parameter adds other types to the search 
  22. #> 
  23.  
  24. param
  25. [Parameter(Position=0, Mandatory=$TRUE, ValueFromPipeline=$TRUE)]   
  26. [string] $distinguishedname
  27. [Parameter(Position=1, Mandatory=$FALSE, ValueFromPipeline=$FALSE)]     
  28. [bool] $addOtherTypes = $false 
  29.  
  30. # Start of function 
  31.  $members = @() 
  32.  
  33.  $this = (Get-QADGroup $distinguishedname).member | Get-QADObject 
  34.  $this | foreach
  35.       if ($_.type -eq ‘user’) { 
  36.           $members += $_ 
  37.       } 
  38.       elseif ($_.type -eq ‘group’) { 
  39.           Write-Host "Adding sub group $_" 
  40.           $members += Get-RecursiveGroupMembership $_.dn $addOtherTypes 
  41.       } 
  42.       else
  43.           if ($addOtherTypes -eq $true) { 
  44.               $members += $_ 
  45.            } 
  46.            else
  47.               Write-Host "Non user/group member detected. Not added. Use -addOtherTypes flag to add." 
  48.            } 
  49.        } 
  50.     } 
  51.     return $members 
  52.  
  53. function Audit-QuickGroup { 
  54. <# 
  55. .SYNOPSIS 
  56.     This function takes the distinguishedName of a group in any domain and writes 
  57.     the results of that group membership to a csv file of the same name. 
  58. .DESCRIPTION 
  59.     This script uses get-recursivegroupmembership function to get the group membership 
  60. .NOTES 
  61.     File Name  : audit.psm1 
  62.     Author     : Dillon (@tealshark on Twitter) 
  63.     Updated by : Thomas Lee tfl@psp.co.uk 
  64.     Requires   : PowerShell V2 CTP3 
  65.     This function is exported 
  66. .LINK 
  67.     http://www.pshscripts.blogspot.com 
  68.     http://tenbrink.us/index.php/2009/01/03/powershelling-audit-reports/ 
  69. .EXAMPLE 
  70. .PARAMETER Name 
  71.     Disginguished name of a group whose membership the script will ascertain. 
  72. #> 
  73.  
  74. param
  75. [Parameter(Position=0, Mandatory=$TRUE, ValueFromPipeline=$TRUE)]   
  76. [string] $Name 
  77.  
  78. # Start of Function 
  79. $Csvdata = Get-RecursiveGroupMembership $name | select name,type,dn,title,office,description | convertto-csv -NoTypeInformation 
  80. $Filename = $Name + ".csv" 
  81. [String]$Reportdate = "Report Generated: " + [datetime]::Now 
  82. $f = new-item -itemtype file $filename 
  83. add-content $f "Audit Report - Active Directory Group - $name" 
  84. add-content $f $reportdate 
  85. add-content $f $csvdata 
  86.  
  87.  
  88. function Audit-MultipleGroups { 
  89. <# 
  90. .SYNOPSIS 
  91.     Gets membership of multiple groups 
  92. .DESCRIPTION 
  93.     This function uses the filtering abilities of the Quest Get-QADGroup cmdlet to  
  94.     get the membership of multiple groups. These are then written to multiple files. 
  95. .NOTES 
  96.     File Name  : get-autohelp.ps1 
  97.     Author     : Dillon (@tealshark on Twitter),  
  98.     Updated by : Thomas Lee tfl@psp.co.uk 
  99.     Requires   : PowerShell V2 CTP3 
  100.     This function is exported 
  101. .LINK 
  102.     http://www.pshscripts.blogspot.com 
  103. .EXAMPLE 
  104.     Left as an exercise for the reader 
  105. .PARAMETER GroupInput 
  106.     The groups you want to audit. 
  107. #> 
  108.  
  109. param
  110. [Parameter(Position=0, Mandatory=$TRUE, ValueFromPipeline=$TRUE)]   
  111. [string] $GroupInput 
  112.  
  113. # Start of function 
  114. # First get groups 
  115. $GroupList = get-qadgroup $groupinput 
  116.  
  117. # Iterate through groups, creating output 
  118.  foreach ($Group in $GroupList) { 
  119.      Write-Host $group.dn 
  120.     $GroupMembers = Get-RecursiveGroupMembership $group.DN | select name,type,dn,title,office,description | convertto-csv -NoTypeInformation 
  121.     #now create file 
  122.     $filename = $Group.Name + ".csv" 
  123.     [String]$reportdate = "Report Generated: " + [datetime]::Now 
  124.     $file = New-Item -ItemType file $filename -Force 
  125.     Add-Content $file "Audit Report - Active Directory Group Membership" 
  126.     Add-Content $file $reportDate 
  127.     Add-Content $file $groupMembers 
  128.   } 
  129.  
  130. # End of Module 

Creating the Manifest

I used the New-ModuleManifest cmdlet to produce the basic module manifest, the .psd1 file. I then did a bit of editing with PowerSHell plus to achieve this final manifest:

  1. # Module manifest for module 'audit' 
  2. # Generated by: Thomas Lee 
  3.  
  4. @{ 
  5. # These modules will be processed when the module manifest is loaded. 
  6. NestedModules = 'Audit.psm1' 
  7. # This GUID is used to uniquely identify this module. 
  8. GUID = '5eed72f9-5f1d-4819-973c-63f80ccee415' 
  9. # The author of this module. 
  10. Author = 'Thomas Lee ([email protected]), with functions by dillon.' 
  11. # The company or vendor for this module. 
  12. CompanyName = 'PS Partnership' 
  13. # The copyright statement for this module. 
  14. Copyright = '(c) PS Partnership 2009' 
  15. # The version of this module. 
  16. ModuleVersion = '1.0' 
  17. # A description of this module. 
  18. Description = 'This module is a packaging of audit scripts by Dillon into a single module.' 
  19. # The minimum version of PowerShell needed to use this module. 
  20. PowerShellVersion = '2.0' 
  21. # The CLR version required to use this module. 
  22. CLRVersion = '2.0' 
  23. # Functions to export from this manifest. 
  24. ExportedFunctions = ('Audit-QuickGroup', 'Audit-MultipleGroups'
  25. # Aliases to export from this manifest. 
  26. ExportedAliases = '*' 
  27. # Variables to export from this manifest. 
  28. ExportedVariables = '*' 
  29. # Cmdlets to export from this manifest. 
  30. ExportedCmdlets = '*' 
  31. # This is a list of other modules that must be loaded before this module. 
  32. RequiredModules = @() 
  33. # The script files (.ps1) that are loaded before this module. 
  34. ScriptsToProcess = @() 
  35. # The type files (.ps1xml) loaded by this module. 
  36. TypesToProcess = @() 
  37. # The format files (.ps1xml) loaded by this module. 
  38. FormatsToProcess = @() 
  39. # A list of assemblies that must be loaded before this module can work. 
  40. RequiredAssemblies = @() 
  41. # Lists additional items like icons, etc. that the module will use. 
  42. OtherItems = @() 
  43. # Module specific private data can be passed via this member. 
  44. PrivateData = '' 

The Results

It turns out that converting a set of script files, like Dillon created initially, into a module (as above) is easy. The syntax of the module file turns out to be a bit tricky, and the error messages and help text in CTP3 are woefully inadequate.

Here’s what this module looks like at runtime:

PS MyMod:\> # Note the module is not yet loaded so you get no output from Get-module

PS MyMod:\> Get-Module audit
PS MyMod:\> # So import the module, then look at module details

PS MyMod:\> Import-Module audit
Importing Module Audit.psm1
PS MyMod:\> Get-Module audit

Name              : audit
Path              : C:\Users\tfl\Documents\WindowsPowerShell\Modules\audit\audit.psd1
Description       : This module is a packaging of audit scripts by Dillon into a single module.
Guid              : 5eed72f9-5f1d-4819-973c-63f80ccee415
Version           : 1.0
ModuleBase        : C:\Users\tfl\Documents\WindowsPowerShell\Modules\audit
ModuleType        : Manifest
PrivateData       :
AccessMode        : ReadWrite
ExportedAliases   : {}
ExportedCmdlets   : {}
ExportedFunctions : {[Audit-QuickGroup, Audit-QuickGroup], [Audit-MultipleGroups, Audit-MultipleGroups]}
ExportedVariables : {}
NestedModules     : {Audit.psm1}

PS MyMod:\> # Here – use AutoHelp feature to get help on the exported function/
PS MyMod:\> Get-Help Audit-QuickGroup

NAME
    Audit-QuickGroup

SYNOPSIS
    This function takes the distinguishedName of a group in any domain and writes
    the results of that group membership to a csv file of the same name.

SYNTAX
    Audit-QuickGroup [-Name] [<String>] [-Verbose] [-Debug] [-ErrorAction [<ActionPreference>]] [-WarningAction [<ActionPreference>]] [-ErrorVariable [<String>]] [-WarningVariable [<String>
    ]] [-OutVariable [<String>]] [-OutBuffer [<Int32>]] [<CommonParameters>]

DETAILED DESCRIPTION
    This script uses get-recursivegroupmembership function to get the group membership

RELATED LINKS
http://www.pshscripts.blogspot.com
http://tenbrink.us/index.php/2009/01/03/powershelling-audit-reports/

REMARKS
    To see the examples, type: "get-help Audit-QuickGroup -examples".
    For more information, type: "get-help Audit-QuickGroup -detailed".
    For technical information, type: "get-help Audit-QuickGroup -full".

What I learned

This was an interesting exercise. It was pretty easy, but I did stumble a bit with the module (how I wish there has been better documentation on modules with CTP3!). Here are some of my take-aways relating to PowerShell modules in CTP3:

  1. Turning a set of inter-related scripts into a module is both easy, and a good thing!
  2. If you have a module that you want to also have a manifest with, they can both have the same file name but with different extensions (the module itself in a .psm1 file and the manifest in a pds1 file).
  3. To export only a subset of the functions in the .psm1 file, you use the ExportedFunctions feature in the manifest.
  4. To export multiple functions you enclose the set of functions as a string array inside the parenthesis. See this in line 24 above. This format was not all that obvious at first.
  5. You can add statements into the module that are executed when you import the module. See Line 2 in the module – this prints out a short message when you import the module. This has some great potential – thanks to Jeffrey Snover for the tip!
  6. If you import a module (using import-module as above) you can generally remove it using remove-module. This aids in testing!

There’s certainly room for improvement in this module. One thing that could be done would be to check to see if the Quest QAD tools were installed and issue a warning message if not (even better, if the tools are not found the script could go get them and install them for you auto-magically!). There should also be some trap or try/catch statements in the functions to better handle errors. Some auditing of the functions usage could also be implemented.

Modules are pretty cool – I hope this helps you understand them a bit better!