Friday, July 20, 2018

My Book Scripts

I saw a comment over on Amazon relating to my last PowerShell book (see Amazon Book Listing) from Long Time Programmer. His comment is that he couldn’t download the code. I wish there was a way I could comment on his comment as there is a way. I’ve put all my scripts up on GitHub!  If you go to https://github.com/doctordns/PowerShellCookbook you can see the scripts there.  Although I have to say some of them – getting the scripts onto GitHub is a work in progress.

As an aside and for background: the publication process at the time this book was published had a few issues.  The web site used to enter content  was literally eating content so we switched over to word at last hour. In doing so, the longer-line scripts ended up broken in the final PDF and thus the published version.

To be helpful to my readers, I’ve slowly retrieved the scripts from inside the VMs and have published them to GitHub, Which is less simple than it sounds and it not yet complete. At present, I’ve ported over the recipe scripts for chapters 1-4, 8, 10, 11 (7 out  of 13). And I hope to have the updates soon.
Please download any of the scripts – and file issues if you find problems.

[Later]
The conversion has been completed and I've created a version 1.0 of the scripts on the GitHub repository. . You can consume the scripts by navigating the GitHub UI or you can take a fork and clone to a local machine. The release mechanism in GitHub provides a zipped up Go to the GitHub Release page and download a .gz or .zip file depending on your tastes. I may do some further tidying up. 

Wednesday, July 18, 2018

Please Buy This PowerShell Conference In A Book

psbook

A couple of months ago, M:Ike Robbins (the tech editor of my last PowerShell book (https://www.amazon.co.uk/dp/B073RP2SNZ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1), sent me mail about a project that he and a few others were planning. The idea was to develop a PowerShell Conference in a book. Mike invited some of the big PowerShell community members to each contribute one chapter. The proceeds are intended to help the DevOps community. Any royalties are to go towards OnRamp Scholarships with the DevOps Collective. Of course I said yes.

Well – now that book is published to which I have contributed a chapter. You can read about the book and buy it here: https://leanpub.com/powershell-conference-book. The book has an impressive list of contributors and is pretty reasonably priced! Of course, if you are feeling generous, LearnPub is happy to enable you to pay more.

The On-Ram Scholarship is a great cause, bringing new people into the DevOps field. You can read about the scholarship here: https://powershell.org/summit/summit-onramp/onramp-scholarship/

My chapter in the book is entitled ‘A Lap Around .NET’ in which I look at what is .NET and some of the things you can do with it.

Saturday, July 14, 2018

Keeping PowerShell Modules Up To Date

At one time, many (most?) IT Pros did not worry to much about updating PowerShell modules,relying for the most part on whatever cmdlets come with the Application, PowerShell, and/or the OS. But times have changed. With the release of Windows PowerShell 5.1, work on modules both inside and outside Microsoft has not stopped. And a number of modules now have updates that might be useful.

Another big change in the PowerShell world is the movement towards holding these new versions on Repositories that you can access via built-in commands (i.e. Find-Module, Update-Module, etc). The question then becomes what modules need updating? Turns out there is a script or two for that!

The first question is whether you care enough about module updates to worry about dealing with updates, and the side effects of module changes.

As I was writing this article, I encountered an interesting example of this issue. The version of the PSReadline module has been updated  to Version2.0 This version has a breaking change in how you set UI token colours. it took a while to sort out but it drove home to me the need to test new versions and not just update because you can. Unless, I suppose, you like living on the edge.

So how do you tell what modules need updating. And as ever, there’s a script for that ™.

Here is a simple function that looks at all the modules you have on your system (well those pointed to via $env:PSModulePath), and checks to see if that module is available via the PSGallery. For every module the founction returns an object with three properties: the module name, the version on the local system and the version on PSGallery. For modules that do not exist on PSGallery, the script returns a PSGallery version of ‘zero’. Here’s the function:

Function Get-ModuleVersionInformation {

[Cmdletbinding()]
Param()

# Startup
$Start = Get-Date
Write-Verbose 'Get-ModuleVersionInformation'
Write-Verbose 'started at: [$start]'

# Get the modules on the local system
$Modules = Get-Module -ListAvailable -Verbose:$False
Write-Verbose ("{0} modules locally" -f $modules.count)

# For each module, see if it exists on PSGallery
# Create/emit an object for each module with the name,
# and the version number of local and remote versions
Foreach ($Module in $Modules) {
  Write-Verbose "Processing $($module.name)"
  $UpdateHt         = [ordered] @{}    # create the hash table
  $UpdateHt.Name    = $Module.Name     # Add name
  $UpdateHt.Version = $Module.Version  # And local version

try {
#  Find module, and add gallery version number to hash table
    $GalMod = Find-Module $Module.name -ErrorAction Stop
    $Updateht.GalVersion = $GalMod.Version
  }
  # here - find module could not find the module in the gallery
Catch {  
   # If module isn't in the gallery
  $Updateht.GalVersion = [System.Version]::new(0,0) 
  }

# now emit the object
New-Object -TypeName PSObject -Property $UpdateHt

} # End foreach

$End = Get-Date
Write-Verbose "Stopped at: [$End]"
Write-Verbose "Took $(($End-$Start).TotalSeconds) seconds"
  
} # End Function

On my system, the output looks like this:

Psh[Cookham24:C:\foo]> $mods = Get-ModuleVersionInformation
Psh[Cookham24:C:\foo]> $mods

Name                     Version     GalVersion
----                     -------     ----------
Buildlab                 1.0         0.0       
NetCmdlets               16.0.6446.0 16.0.6592.0
ScriptBrowser            1.3.2.0     1.3.1.0   
tfl                      1.0         0.0       
Azure.AnalysisServices   0.5.0       0.5.2     
Azure.Storage            4.1.0       4.3.1     
AzureRM                  5.2.0       6.4.0                      
AzureRM.RedisCache       4.1.0       0.0       
AzureRM.Relay            0.3.1       0.0
 

… Etc.

Loaded with this function you can then do this:

$zero = [System.Version]::new(0,0)
foreach ($mod in $mods) {
  If ($mod.galversion -eq $zero) {
  $msg = "Module [$($mod.name)] does not exist in PSGallery"
  $msg
  continue
  }
  If ($mod.galversion -gt $mod.version){
  $msg = "Module [$($mod.name)] should be updated from v$($mod.version) to v$($mod.galversion)"
  }
  Else {
  $msg = "Module [$($mod.name)] does not need to be updated - current version $($mod.version)"
  }

$msg
} # End foreach

The output, again in my main workstation looks like this:

Module [Buildlab] does not exist in PSGallery
Module [NetCmdlets] should be updated from v16.0.6446.0 to v16.0.6592.0
Module [ScriptBrowser] does not need to be updated - current version 1.3.2.0
Module [tfl] does not exist in PSGallery
Module [Azure.AnalysisServices] should be updated from v0.5.0 to v0.5.2
Module [Azure.Storage] should be updated from v4.1.0 to v4.3.1
Module [AzureRM] should be updated from v5.2.0 to v6.4.0
Module [AzureRM.AnalysisServices] should be updated from v0.6.2 to v0.6.9
Module [AzureRM.ApiManagement] should be updated from v5.1.0 to v6.1.1
Module [AzureRM.ApplicationInsights] should be updated from v0.1.1 to v0.1.4
Module [AzureRM.Automation] should be updated from v4.2.0 to v5.0.1
Module [AzureRM.Backup] should be updated from v4.0.2 to v4.0.6
Module [AzureRM.Batch] should be updated from v4.0.4 to v4.1.1
Module [AzureRM.Billing] should be updated from v0.14.0 to v0.14.3

This leaves me with a bit of work to do – updating PSReadLine, as I discovered did have some unfortunate side effects (and I suspect I am not the only one to have fallen over this issue!).

If I was brave, I could have updated that last script fragment to actually update each of the older modules. Not sure I’m ready for that, just yet…