My presentation at the first meetup of the French PowerShell User Group

Today I presented a session on Parsing Data using PowerShell at the first meeting of the French PowerShell User Group.

This User Group is organized by a couple of Francophone PowerShell MVPs, including me, from different parts of the world.

Below are the presentation, the scripts and the recording of the meeting. Even if you don't speak the language of Molière you should be able to follow along with the PowerShell language.

Presentation (PPTX) and Scripts : Github Repository of FRPSUG

Registration to our next events: Meetup.com

Slack: Feel free to drop by on our channel #french on powershell.slack.com (register first)

Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.


PowerShell Tip - Generate a list of Mac Addresses

While playing in my lab I needed to create a bunch of fake Devices in System Center Configuration Manager (SCCM). When creation devices you need two pieces of information, the computer name and the Mac Address of the device.

I used the following method to generate my list of mac addresses.

# First, get a list of mac address.
1..150 | ForEach-Object { '{0:X12}' -f $_ }
# Second step: Before we import we need to add a colon ":" every two characters
1..150|%{((('{0:X12}' -f $_) -split '(..)')|?{$_}) -join ":"}

What is happening here

  1. We list from the number 1 to 150
    1. 1..150


PowerShell - Composite Formatting references (-f Operator)

If you play often with PowerShell you might have encountered something called "Composite Formatting". What is that ? Here is a quick example

"Welcome to {0}" -f "LazyWinAdmin.com"

Each format item takes the following form and consists of the following components:
The matching braces "{" and "}" are required.

Composite Formation

The .NET Framework composite formatting feature takes a list of objects and a composite format string as input. A composite format string consists of fixed text intermixed with indexed placeholders, called format items, that correspond to the objects in the list. The formatting operation yields a result string that consists of the original fixed text intermixed with the string representation of the objects in the list.

# Numeric Format Strings #

# The Decimal ("D") Format Specifier
"{0:D}" -f 50999994 #50999994
"{0:D10}" -f 50999994 #0050999994
"{0:D6}" -f -1234 #-001234


PowerShell/Pester - Make sure your parameters are separated by an empty line

Today, I continue with another post on Pester. I want to check that each of my parameters declared in my PARAM() block is separated by a empty line.

This will help bring clarity to my code and make it easier to read for other people.

Here is an example, I don't want this:

Instead, I want all the comment based help in that format


PowerShell/Pester - Make sure your Comment Based Help is not indented

While writing some PowerShell Pester tests for my module AdsiPS, I wanted to make sure for each functions that all the help keywords of the comment based help were not indented.

Depending of the script editor you are using, the number of spaces or tabs might differ and once published on GitHub the code might looks not so pretty.

My goal is just to keep my code clean and enforce the same practice across all the functions.

Here for example, I don't want this:
Instead, I want all the comment based help in that format


Launch of / Lancement du French PowerShell User Group

[English below]

Depuis un moment, dans la Communauté PowerShell francophone,  je vois un certain nombre de développeurs, administrateurs et MVP  d’un peu partout dans le monde exprimer le désir d’avoir un groupe d’utilisateurs PowerShell.

Nous avons tous une famille, un travail, des loisirs et organisé un évènement prend beaucoup de temps, surtout pour trouver des salles, des sponsors, des présenteurs, etc…

Donc, … il y a quelques semaines j’ai commencé une conversation avec quelques gars du domaine et lancer l’idée d’un groupe d’utilisateurs uniquement en ligne (pour le moment) en utilisant Meetup.com / Google Hangout On Air / Youtube Live. Cela facilite énormément l’organisation, permet l’enregistrement du meeting automatiquement et à tous d’assister au meeting peu importe l’endroit.


PowerShell 10th Anniversary - Open Source / Running on Linux and Mac OS X

The PowerShell Team just dropped a bombshell !

Windows PowerShell is now a cross platform technology with the availability of PowerShell on Linux and Mac !! .... AND.... The PowerShell team is Open Sourcing Windows PowerShell (.Net) and PowerShell Core (.Net Core) !! This is so Cool !!!

Today (2016/08/18) also marks the 10th Anniversary of PowerShell ! Quite a surprise that the PowerShell team prepared for us :-) Given the recent changes in leadership and culture, It is really nice to see Microsoft taking that direction.

PowerShell is now Open Source

Under the MIT License, PowerShell is now an Open Source Software (OSS).

This was made possible with the release of the .NET Core Framework, foundational libraries called CoreFX. A framework available on Windows, OS X and Linux! .NET Core is cross-platform and open source.

PowerShell Core is fairly recent and does not offer all the cmdlets available on PowerShell yet since they don't rely on the same Net Framework as Windows PowerShell (.NET). As a side note, Windows Server 2016 Nano Edition (aka Nano Server) is running on PowerShell Core.

PowerShell is now a Cross Platform technology

In addition to Windows Client and Server, PowerShell is now available on the following operating systems:
  • Linux
    • Ubuntu 14.04 \ 16.04
    • CentOs 7.1
    • RHEL 7
  • MAC OS X
    • OS X 10.11

Download / Test / Contribute

The source are located on Github on the following repository https://github.com/PowerShell/PowerShell

It also worth to note that the PowerShell Team is also providing some nice examples/demos on their GitHub repository: https://github.com/PowerShell/PowerShell/tree/master/demos

Some of the examples available:

Some of those are also demoed in a video here:

Installing PowerShell Core on Linux and Mac

Here is the documentation on how to proceed with the installation of PowerShell Core on Linux and Mac. https://github.com/PowerShell/PowerShell/blob/master/docs/installation

At the time I'm writing this, I only see documentation on how to install PowerShell Core on Linux

PowerShell Core on Linux

PowerShell Core on MAC OS X


PowerShell/WinForms - Row Header

If you are creating Windows Forms (WinForms) using PowerShell with tools such as PowerShell Studio from Sapien, you might have some scenario where you want to use Row Header instead of Column Header in a DataGridView control.

Those can be controlled using the properties RowHeaderVisible and ColumnHeaderVisible.

Assuming you already have a form with a Datagridview in it, you will need to do the following:
  • Create a Column
  • Create a Row with the Header value (and optionally a value for the first column)
  • Add the Row to the DataGridView
  • Set RowHeaderVisible to $true
  • Set ColumnHeaderVisiable to $false (Optional)
(The example can be download on my github)

Creating a Column

# Create Column object
$NewColumn = New-Object -TypeName System.Windows.Forms.DataGridViewTextBoxColumn
$NewColumn.Name = "Column1"
$NewColumn.HeaderText = "Column1"

# Add the Column to the Datagridview


Offline Domain Join - Recreating the Blob file using PowerShell

When you need to join a machine to the Active Directory It is a pretty straight forward task using either the User Interface or the PowerShell cmdlet available for that usage.

However in some situation you don't have network connectivity and need to rely on Offline Domain Join, using the Djoin.exe tool. Typically you use djoin in two phases. First you generates a provisioning file that you drop on a newly deployed machine. In the second phase you run djoin with the file as a parameter and the machine is joined to the domain without connection to the domain controller.

My problem
Using that same method, I recently had a tricky problem to solve. The environment where I was performing this was very locked down, not allowing me to copy files to the new provisioned machine.

Fortunately the system handling the deployment could perform action on other systems and gather data. I could rely on something like System Center Orchestrator (or SMA) and get the content of the Blob file over HTTP/HTTPS by invoking a runbook.

Recreating the djoin file with the content was a bit trickier. Djoin is really picky on how the file is created. (see here and here for more information)


Montreal PowerShell User Group #03 - Future of our user group

Join us for the Montreal PowerShell User Group #03 meeting on the Tuesday 24th of May 2016 from 6:00pm to 8:00pm at the Warner Brothers Games Studio.

Registration: Seats are limited, please RSVP on Meetup.com

This will be a social event, a bit different from the previous ones. We will discuss the future of the user group and gather your feedback.

There is no technical presentation planned but if the time permits it, you are welcome to show off/talk about some of your success stories using PowerShell or bring your scripts if you need help.

We plan to have some Pizza & Pop Corn!

More details on meetup.com

Hope to see you there!


Tuesday, 24th of May 2016 from 6:00pm to 8:00pm


Warner Brothers Games - 888 Maisonneuve Est - 6th Floor
Room: Jack Warner (In front of elevators)


Using Pester to test your Manifest File

In my previous post I got started with Pester and wrote my first test against the Comment Based Help of my module AdsiPS.

Next, I wanted to write a Pester test against the Manifest File of AdsiPS module. I want to make sure all the basic information of the module is referenced in this file. Mike Robbins wrote a great article on Dynamic Unit Tests where he is touching some of the points I want to cover today.

But before I get into the code, a small reminder on the Manifest file's role.

What is a Manifest File ?

A module manifest is a Windows PowerShell data file (.psd1) that describes the contents of a module and determines how a module is processed. The manifest file itself is a text file that contains a hash table of keys and values. You link a manifest file to a module by naming it the same as the module, and placing it in the root of the module directory.

For simple modules that contain only a single .psm1 or binary assembly, a module manifest is optional. However, it is recommended that you use a module manifest whenever possible, as they are useful to help you organize your code and to maintain versioning information. More info.
(You'll find at the end of this article the command that I use to generate my manifest.)


Using Pester to test your Comment Based Help

Update 2016/11/25: Updated the code to support functions where there is no parameter declared (Thanks Wojciech Sciesinski !!!)

I remember attending a meeting on Pester presented by Dave Wyatt back in November 2014 during my first MVP Summit.

A couple of well known PowerShellers were there: Boe Prox, Emin Atac, Adam Driscoll, Mike Robbins, Fabien Dibot, Jan Egil Ring, Steve Murawski, ...  It was a great event, great to finally meet all those guys...

Anyway, at the time Pester looked pretty neat but since I only played with it a couple of times and never really invest or commit myself to create tests for each of my scripts or modules.

During the Microsoft MVP Summit 2014 week (Bellevue, WA, USA)
Evening event organized by Dave Wyatt on Pester.


Create a function/Cmdlet alias using the [Alias()] attribute

Just wanted to share a small PowerShell tips that Kirk Munro found.
You can declare a function or Cmdlet Alias using the following technique:

function Get-This
    PARAM (
    Write-Output "Param1 = $param1"

Get-That -Param1 "Hello World"

According to Jason Shirk this has been added in PowerShell v4.0:
"Support for the alias attribute on a function or cmdlet (works in C# too!) was added in V4.
It’s most valuable in a binary module because it’s harder to create aliases via IModuleAssemblyInitializer and when you do via that interface"


Active Directory - How to grant an account to use Sync-ADObject ?

During an onboarding process, I had to create some accounts on a remote site where the Exchange Role is installed. There, the account can be mail-enabled. We do this because the information will get replicated to Office365 faster and we will be able to proceed with other automated tasks.

Once the account is created, mail-enabled, sync to Office365, added to a couple of DLs, I needed to sync back the account to my local Domain Controller.

This can be done using the Cmdlet Sync-ADobject from the Active Directory module.

Of course you will need to give explicit permission to an account to perform this action else you will get the following message:

"Sync-ADObject : Insufficient access rights to perform the operation"

To grant permission, you'll need to launch the ADSIEdit tool and grant permission at the root of the domain for "Replication Synchronisation"

Once the permission granted, you'll see the following

Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.


PowerShell/SCSM - Get Review Activities Rejected in the last 60 days

In the following post I demonstrate how you can retrieve all the rejected Review Activities from the last 60 days. I also include the DisplayName, the Decision and the Comment of the Reviewer.

Hope this help some people out there.

# Smlets Module
Import-module -name smlets

# Capture the SR Failed Status
$RAStatusFailed = Get-SCSMEnumeration -Name ActivityStatusEnum.Failed$

# Capture the date from where we are searching
$RAModifiedDay = (get-date).Adddays(-60)

# Get the Manual Activity Class
$RAClass = Get-SCSMClass -Name System.WorkItem.Activity.ReviewActivity$

# Get the Criteria Class
$CriteriaClass = “Microsoft.EnterpriseManagement.Common.EnterpriseManagementObjectCriteria”

# Define the filter
$Filter = "Status = '$($RAStatusFailed.Id)' AND LastModified > '$RAModifiedDay'"

# Create the Criteria Object
$CriteriaObject = new-object $CriteriaClass $Filter,$RAClass

# Get the Reviewer relationship classes
$RAHasReviewerClass = Get-SCSMRelationshipClass System.ReviewActivityHasReviewer$
$ReviewerIsUserClass = Get-SCSMRelationshipClass System.ReviewerIsUser$

# Get the RA rejected in the last 60 days
Get-SCSMObject -criteria $CriteriaObject |
    ForEach-Object -Process {

        # Current Review Activity
        $RA = $_

        # Get the rejected review(s) on this RA
        $RejectedReview = Get-SCSMRelatedObject -SMObject $RA -Relationship $RAHasReviewerClass | Where {$_.decision.displayname -eq 'Rejected'}

        foreach ($item in $RejectedReview)
            # Get the reviewer information
$ReviewerObj = Get-SCSMRelatedObject -SMObject $Item -Relationship $ReviewerIsUserClass
            # Create a new PowerShell Object
                ReviewActivityName = $RA.Name
                ReviewerDisplayName = $ReviewerObj.displayname
                Decision = $item.decision.displayname
                Comments = $item.comments -as [string]
    }#| Format-List


PowerShell/SCSM - Get Manual Activities Completed per Assigned user in the last month

I wanted to expend a bit on the previous post which retrieved all the Manual Activities completed in the last month.

I want to go a step further and get the top Users who closed the most Manual Activities in that period.

# Smlets Module
Import-module -name Smlets

# Get the Manual Activity Class
$MAClass = Get-SCSMClass -Name System.WorkItem.Activity.ManualActivity$

# Get the Manual Activity Completed Status Enumeration
$MAStatusCompleted = Get-SCSMEnumeration -Name ActivityStatusEnum.Completed$

# Get the starting date from where we are searching
$MAModifiedDay = (Get-date).Adddays(-30)

# Get the Criteria Class
$CriteriaClass = "Microsoft.EnterpriseManagement.Common.EnterpriseManagementObjectCriteria"

# Define the Filter
$Filter = "Status = '$($MAStatusCompleted.Id)' AND LastModified > '$MAModifiedDay'"

# Create de Criteria Object
$CriteriaObject = new-object $CriteriaClass $Filter, $MAClass

# AssignedUser RelationshipClass
$RelationshipClass_AssignedUser = Get-SCSMRelationshipClass -Name System.WorkItemAssignedToUser$

# Search for Manual Activities, show the Ticket ID and the AssignedTo User's displayname
# Group per AssignedTo User and sort per Count
Get-SCSMObject -criteria $CriteriaObject|
    Select-Object -property Name, @{
            (Get-ScsmRelatedObject -SMObject $_ -Relationship $RelationshipClass_AssignedUser).displayname
    Group-Object -Property AssignedTo |
    Sort-Object -Property Count -Descending


PowerShell/SCSM - Get Manual Activities Completed in the last month

I got an interested question from a reader that asked how he could get all the Manual Activities completed in the last 30 days using one Filter.

I got some trouble working with Get-SCSMObject and multiple conditions in the -Filter parameter, but got it working using the Criteria parameter. Hope this help!

# Import Smlets Module
Import-module -name Smlets

# Get the Manual Activity Class
$MAClass = Get-SCSMClass -Name System.WorkItem.Activity.ManualActivity$

# Get the Manual Activity Completed Status Enumeration
$MAStatusCompleted = Get-SCSMEnumeration -Name ActivityStatusEnum.Completed$

# Get the starting date from where we are searching
$MAModifiedDay = (Get-date).Adddays(-30)

# Get the Criteria Class
$CriteriaClass = "Microsoft.EnterpriseManagement.Common.EnterpriseManagementObjectCriteria"

# Define the Filter
$Filter = "Status = '$($MAStatusCompleted.Id)' AND LastModified > '$MAModifiedDay'"

# Create de Criteria Object
$CriteriaObject = new-object $CriteriaClass $Filter, $MAClass

# Search for Manual Activities
Get-SCSMObject -criteria $CriteriaObject


Windows Management Framework (WMF) 5.0 RTM released (again)

Microsoft just re-released the new version of Windows Management Framework (WMF) 5.0 RTM for Windows Server 2012 R2, Windows Server 2012, Windows 2008 R2 SP1, Windows 8.1, and Windows 7 SP1.

The PowerShell Team previously released WMF 5.0 RTM two months ago but it was pulled-back mainly because of the $PSmodulePath issue.

Download WMF5

Changes in the republished packages

  • The KB numbers of these packages (KB3134758, KB3134759, and KB3134760) are different than previously released WMF 5.0 RTM packages (KB3094174, KB3094175, and KB3094176).
  • These packages have fixes only for the PSModulePath issue compared to the previously released WMF 5.0 RTM packages.

Uninstall previously released WMF 5.0 RTM packages

You must uninstall previously released WMF 5.0 RTM (KB3094174, KB3094175, and KB3094176) packages.

No impact to Windows 10 and Windows Server 2016 Technical Preview builds

Windows 10 and Windows Server 2016 Technical Previews builds are not impacted by the above mentioned PSModulePath issue. This issue was only impacting down-level systems where WMF 5.0 RTM can be installed.

To install WMF 5.0 by using Command Prompt

  1. After you have downloaded the correct package for your computer's architecture, open a Command Prompt window with elevated user rights (Run as Administrator). On the Server Core installation options of Windows Server 2012 R2 or Windows Server 2012 or Windows Server 2008 R2 SP1, Command Prompt opens with elevated user rights by default.
  2. Change directories to the folder into which you have downloaded or copied the WMF 5.0 installation package.
  3. Run one of the following commands.

    • On computers that are running Windows Server 2012 R2 or Windows 8.1 x64, run Win7AndW2K8R2-KB3134760-x64.msu /quiet
    • On computers that are running Windows Server 2012, run W2K12-KB3134759-x64.msu /quiet
    • On computers that are running Windows Server 2008 R2 SP1 or Windows 7 SP1 x64, run Win7AndW2K8R2-KB3134760-x64.msu /quiet
    • On computers that are running Windows 8.1 x86, run Win8.1-KB3134758-x86.msu /quiet
    • On computers that are running Windows 7 SP1 x86, run Win7-KB3134760-x86.msu /quiet

Overview of all scenarios enabled by WMF 5.0

  • New and updated cmdlets based on community feedback
  • Generate Windows PowerShell cmdlets based on an OData endpoint with ODataUtils
  • Manage .ZIP archives through new cmdlets
  • Interact with symbolic links using improved Item cmdlets
  • Network Switch management with Windows PowerShell
  • DSC authoring improvements in Windows PowerShell ISE
  • 32-bit support for the configuration keyword in DSC
  • Audit Windows PowerShell usage by transcription and logging
  • Extract and parse structured object out of string content
  • Configure DSC’s Local Configuration Manager with the meta-configuration attribute
  • Configure piece by piece with partial configurations in DSC
  • Manage with cross-computer dependencies in DSC
  • More control over configurations in DSC
  • Find more detail about configuration status in DSC
  • Support for -? during DSC configuration compilation
  • Support for DSC RunAsCredential
  • Rich information for DSC LCM State
  • Side-by-Side installation of DSC Resources
  • PSDesiredStateConfiguration Module version updated to 1.1
  • Discover and install software with PackageManagement
  • Discover modules and DSC resources with PowerShellGet
  • Develop with classes in Windows PowerShell
  • More control and remoting in Windows PowerShell Debugging
  • Report configuration status from DSC to a central location
  • Software Inventory Logging.


PowerShell 5.0

Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.


PowerShell/SCSM - Get the Work Item parent of an Activity

In the last couple of months, I have been busy on some projects involving System Center Service Manager (SCSM), System Center Orchestrator (SCORCH) and Cireson Portal/Asset Management and I had to script a couple of repetitive tasks using PowerShell.

The following solution allows you to retrieve the parent Work Item of an Activity.

This is useful when you are using a Runbook Activity in your workflow that will invoke a Runbook inside System Center Orchestrator.

Example: In the case where you have a Work Item, a Service Request for instance, with bunch of activities (Review Activity (RA), Manual Activity (MA), Runbook Activity (RBA), etc... ). You could have a Runbook Activity (RBA) calling a System Center Orchestrator runbook.

From a SCORCH perspective it would be useful to find which Work Item the runbook activity belongs to if you want to perform some actions on the Work Item itself and other Activities.
Example: Edit the Work Item Title, Add a reviewer, Skip any Activities with a particular stage, etc...

Here is a PowerShell function that can just do this job for you: Get-SCSMWorkItemParent.


Microsoft MVP 2016 for Cloud and Datacenter Management

It is a great pleasure and honor to receive for a third year the PowerShell MVP Cloud and DataCenter Management MVP Award!!!

Chère/Cher Francois-Xavier Cat,
Félicitations! Nous sommes heureux de vous remettre le titre MVP Microsoft® 2016! Ce titre est accordé aux leaders d'exception de la communauté technique qui partagent activement leur expertise pratique de grande qualité. Nous apprécions vos remarquables contributions dans les communautés techniques Cloud and Datacenter Management lors de cette année passée.

HUGE thanks to my family, friends and people who support me!!!!!

Some updates:
In the recent months, I have been really busy on many projects at work involving, of course a great deal of automation and using the System Center Suite. Working in the game industry is really fun but you’ve got to keep up the high pace. I'll start blogging soon and I already have a bunch of drafts. There are also a couple of nice scripts and Github projects that I'd like to get out there, and get them eventually published on the PowerShell gallery.

Another reason why I wasn't super present, my girlfriend is currently studying abroad. She returns only during the winter holidays and summer breaks, so I was away from my computer. One has to know one’s priorities!! :-)

Last year, I had organised a few successful PowerShell User Group meetings and I'm looking forward to organizing some more in the coming weeks. The Meetup group is growing fast and it currently shows 126 members; I might need to find a bigger meeting room!!!

Stay tuned!