Enabling Requestable Roles in SailPoint IdentityNow using PowerShell

Recently I wrote this post about Retrieving, Creating, and Managing SailPoint IdentityNow Roles using PowerShell.

Last week SailPoint enhanced Roles with the ability to request them. The details are located on Compass here.

I had a number of Roles that we wanted to make requestable, so rather than opening each and using the Portal UI to enable them, I did it via the API using PowerShell.

As per my other Roles post, a JWT Bearer Token is required to leverage the Roles API’s. That is still the same. I covered how to obtain a JWT Bearer Token specifically for interacting with these API’s in this post here. I’m not going to cover that here so read that post to get up to speed with that process.

Enabling Roles to be Requestable

The following script queries to return all Roles, iterates through them to make them requestable. Update;

  • Line 2 for your IdentityNow Org Nam
  • after Line 9 you can refine the roles you wish to make requestable

Summary

Using the API we can quickly enable existing IdentityNow roles to be requestable.  When creating new Roles we can add in the attribute Requestable with the value True if we want them to be requestable.

Using Invoke-WebRequest calls within a Granfeldt PowerShell MA for Microsoft Identity Manager

MIM Sync Service Account IE Security Settings

If you use PowerShell extensively you should be familiar with the Invoke-RestMethod cmdlet and the ability for PowerShell to call API’s and receive information. The great thing about Invoke-RestMethod is the inbuilt conversion of the results to PowerShell Objects. However there are times when you need the raw response (probably because you are trying to bend things in directions they aren’t supposed to be; story of many of my integrations).

From within Granfeldt PowerShell Management Agent script(s) that use Invoke-WebRequest calls, these will in turn leverage the Internet Explorer COM API on the local machine. That means the account that is performing those tasks will need to have the necessary permissions / Internet Explorer configuration to do so.

Enabling Invoke-WebRequest for the FIM/MIM Synchronization Server Service Account

Logon to your Microsoft Identity Manager Synchronization Server using the Service Account associated with the Forefront Identity Manager Synchronization Service. If you’ve secured the service account properly you will need to temporarily allow that service account to Log on Locally.

FIM Sync Service Account.PNG

Open Internet Explorer and open Internet Options. Select the Security Tab, the Internet zone and select Custom Level.

Locate the Scripting section and set Active scripting to Enable. Set the Allow websites to prompt for information using scripted windows to Disable. Select Ok and Ok.

MIM Sync Service Account IE Security Settings.PNG

With the configuration completed, go back and change back the Forefront Identity Manager Service Accounts’ local permissions so it can’t logon locally.

Your Import / Export Granfeldt PowerShell Management Agent Scripts can now use Invoke-WebRequest where the requests/responses use the Internet Explorer COM API and respect the Internet Explorer security settings for the user profile that the requests are being made by.

Hopefully this helps someone else that is wondering why the scripts that work standalone fail when operating under the FIM/MIM Sync Service Account by the Granfeldt PowerShell Management Agent.

Speeding up PowerShell lookups across large Collections

This week I needed to create a report based on information returned from two queries. The query results where contained in two separate collections (50k+ objects each). Taking the smaller filtered collection and looking up the other collection for the additional information using PowerShell like this proved frustrating slow:

$extraData = $collection2 | Where-Object {$_.UserPrincipalName -eq $collection1.UserPrincipalName } | Select-Object

An alternative then was to query directly (via an API) for the additional information whilst iterating through the main collection rather than searching for it in the other collection e.g.

foreach ($obj in $collection1){ $extraData = Invoke-RestMethod -method GET ...... }

That too was way too slow and wasn’t really being a nice NET citizen for the API on the end of 50k+ queries.

Solution

My solution was to join the two collections of objects and then build my report based off just one collection. Step in the Join-Object function from Warren F.

Join-Object provides a lot of flexibility on how and what to join between collections. For my requirements I just needed to use Join-Object to join based on a common key and bring in all the data from the other collection. That then looked like this in PowerShell;

$reportData = Join-Object -Left $collection1 -Right $collection2 -LeftJoinProperty UserPrincipalName -RightJoinProperty UserPrincipalName -Type AllInLeft
Whilst this one line to join my two collections takes just over an hour to execute my entire report now completes in less than 90 minutes vs the 5 1/2 hours it was previously taking to run. Thx psCookieMonster

Searching and Retrieving your GitHub Gists using PowerShell

GitHub Gists, I love them. I treat them as my personal snippet storage as well as the repository for many posts on this blog. If you are new to them, it is important to know that you can have public and secret Gists. Secret Gists thereby give you your private little snippet storage environment.

At some point though you’re going to want to retrieve a snippet based on a fragment of knowledge, such as an API, keyword or similar. Through the Gist Webpage you can search and it will give you a list of your Gists where your keyword exists and if you hit enter it will give you all Gists.

But what if you want to search your Gists based on other or more complex criteria (public vs secret). Step in the Gist API, and my scripting tool of choice. This post will quickly detail authenticating to GitHub, retrieving all your Gists and then narrowing down the one(s) you’re after. Of course there are PowerShell Modules that can do some of this, but I needed something light and portable without needing to install another module.

If nothing more this is an easy post for me to find, to retrieve my script to then find my Gists.

Obtaining a Personal Access Token

Login to Github using your account and head to https://github.com/settings/tokens and select Generate new token. Give it a description and select gist.

GistToken.PNG

After selecting Generate Token you will be shown your access key. Copy it and store it safely. It won’t be displayed again and is your password to access GitHub.

Simple retrieval and Search Script

Update the following script;

  • Line 2 for your username
  • Line 4 for your token
  • Line 9 for your search term

As it stands the script is looking for Secret Gists (as per line 21). Change to $true for Public. It will find all that meet the search query (line 9) in the Description field. It will then get the Raw Gist contents and output it to the console. Update accordingly for what you want to happen after retrieval.

 

 

 

Nested Virtual PowerShell Desktop Environments on Windows 10 & Windows Server 2019 in Azure – Part 3

Docker Virtual PowerShell Desktop Env to Internet - SaaS

This is the third and likely last post in this series. In Part 1 I introduced the capability to have Virtual PowerShell Environments using Docker and the full Windows 10 / Server 2019 Build 1809 container images. In Part 2 I detailed remotely access the Azure RM Windows 10 / Server 2019 host that contains the Docker Container with our full Windows 1809 environment (and therefore PowerShell Desktop).

In this post I’ll detail building a Docker Image based off of the Windows 1809 Container image. The resulting Docker Image will;

  • create a base PowerShell environment with the necessary PowerShell Modules for performing common Azure based administrative activities
  • using the Docker image for administrative functions
  • be accessible to be started using SSH from other SSH Clients (e.g Putty)

Building a Docker Image based off Windows 1809 Container

Using the capabilities I showed in in Part 2 of this series I’m going to build the image from Azure Cloud Shell that I’ll use to SSH into the Windows 10 AzureRM hosted Virtual Machine.

Having logged in to Azure Cloud Shell and connected to my Azure VM via SSH as detailed in Part 2. I then created a new CMD file named NewImage1809.cmd that has the following command inside it.

docker run -it --name psNov2018 mcr.microsoft.com/windows:1809 powershell

New Image Start

Running the commands hostname and dir c:\program files\WindowsPowerShell\Modules shows that we are inside the Windows 1809 Container Image.

Hostname and Existing Modules.PNG

I used the Cloud Shell Upload option to upload a New Env Setup.ps1 script that contains the PowerShell commands to install a bunch of PowerShell Modules. Using the Cloud Shell Editor I opened the file.

New Env Setup Script

Here is that series of commands.

I can then select the block of commands and paste it into the PowerShell terminal console below and hit enter for it to execute them.

Excute

One by one the modules are installed

Modules Installed

When completed enter exit.

Exit after Module Install

Now we can stop our Container Image.

docker stop psNov2018

Docker stop.PNG

and commit our changes to a new container named ‘powershell-env-image-nov18’

docker commit psNov2018 powershell-env-image-nov18

Docker Commit.PNG

Listing the docker images with

docker image ls

shows our new Image.

Docker Image List.PNG

We can now Run our new image with

docker run -it powershell-env-image-nov18:latest powershell

Run Image.PNG

We can see the modules we installed previously.

Image Module List.PNG

and we can import them.

Import Modules.PNG

Putty to PowerShell Virtual Environment

As good as Azure Cloud Shell is, and as convenient as it is for quick tasks and execution, you’re going to want to use an SSH Client. I’ll show using Putty, but you can use whatever your favourite client is. To connect to the environment I;

  • using the Putty Key Generator I loaded the OpenSSH Private Key generated in Part 1 and saved it in Putty ppk format
  •  using Putty Pageant I can use the ppk formatted key for my SSH session to the Windows 10 1809 host
    • Note: WinSCP can also utilise the ppk key for authentication which makes getting files onto the Host very easy
  • if you find you don’t automatically get your elevated session that allows you to start the Docker Container/Image then create the following registry key on the Windows 10/Server 2019 host and reconnect. DWORD (32-bit) value of 1 for LocalAccountTokenFilterPolicy
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System]
"LocalAccountTokenFilterPolicy"=dword:00000001

I can then connect with Putty using my key, and run the DockerPS.cmd file I showed in Part 2 which outputs the version of PowerShell.

Summary

In this post I’ve shown how to customise a Windows 1809 Container for a Virtual PowerShell environment, along with using client based SSH and SCP tools to connect to and manage the base Host.

Searching & Returning all Objects/Users from a SailPoint IdentityNow Source

There are times when need to get an extract of all objects on an IdentityNow Source. Just a particular Source, not the object from the Identity Cube with attributes contributed from multiple sources.

I’ll cover how I do that in this post, which in turn also handles paging the results from IdentityNow as the SearchLimit is 2500 objects.

The basis of the logic is;

  • Define the Source to retrieve objects from
  • Define the number of results you wish to return per page (maximum is 2500)
  • Page results until you return the base object for all objects on the Source
  • Retrieve the Full Object details for each object

The Script

The following script has been written to run in VS Code and provide a Progress bar using the psInlineProgress PowerShell Module available from the PowerShell Gallery and here. If you are also running this via VSCode, after obtaining psInlineProgress update the psInlineProgress.psd1 file to change Line 36 as shown below. You should be able to find it in C:\Program Files\WindowsPowerShell\Modules\psInlineProgress\1.1

#PowerShellHostName = 'ConsoleHost'
PowerShellHostName = 'Visual Studio Code Host'

Update;

  • Line 3 for your IdentityNow API ClientID
  • Line 5 for your IdentityNow API ClientSecret
  • Line 9 for you IdentityNow Tenant name
  • Line 13 for the ID of the IdentityNow Source you want to retrieve entities from
  • Line 17 for the number of entries to return per page (2500 is the maximum)

Example

The output below shows using the script to return 2591 objects from an IdentityNow Source.

Search and return all objects on an IdentityNow Source

Summary

Using the v2/accounts IdentityNow API we can retrieve the base objects associated with an IdentityNow Source and then call it again with each objectID to retrieve the full object record. This can be useful if you want to then programatically extract and process the information rather than downloading a CSV via the IdentityNow Portal. Say for example ingestion into another system or Identity Management tool. But that’s a post for another time.

Nested Virtual PowerShell Desktop Environments on Windows 10 & Windows Server 2019 in Azure – Part 2

27 Nov 18 Part 3 is available here that details customizing 
an image and accessing it via other SSH clients with elevated
access.

In Part-1 of this series posted yesterday I showed that with Windows 10/Windows Server 2019 we can now have isolated virtual environments for PowerShell Desktop in Azure through containerization.

In this post I’ll show how I plan to leverage this capability from a mobility perspective. What we need to do first is enable elevated (privileged) access to our VM. My Client will be Azure Cloud Shell. My target/host is the Windows 10 1809 Virtual Machine I deployed in the last post.

Enabling SSH Key Based Privileged Authentication to our Windows 10 VM

To setup Key Based Access (over password access, which is required for elevated access) we need to configure the SSH Server and our Client.

SSH Server

On the Windows 10 Azure VM where we installed OpenSSH as per the first post here, we need to start the SSH-Agent. By default it is set to Disabled. Change the Startup Type, Start it and test it by adding the local user to the Agent. Using an elevated PowerShell session on the Azure Windows VM run;

Set-Service ssh-agent -startupType automatic
Start-Service ssh-agent
cd ~\
ssh-add .\.ssh\id_rsa

Add SSH Key to SSH-Agent on Server.PNG

SSH Client

As I’m using Azure Cloud Shell as my client, I started a Cloud Shell Session in my browser.

  • In Azure Cloud Shell generate a SSH Key using SSH-Keygen
    • Remember your passphrase as this will be required for accessing the Windows 10 Azure VM

Client SSH Keygen.PNG

  • Copy the key to the Windows 10 Azure VM
    • Run the command below (after changing it for your username and Windows VM IP Address) and provide your password to copy up the file
cd ~/
scp ./.ssh/id_rsa.pub username@Win10ServerIPAddress:C:\Users\userprofilename\.ssh\authorized_keys\

Copy Public Key from Client to Server.PNG

  • On the Server if C:\ProgramData\ssh\administrators_authorized_keys exists add your Public key that you copied into your home folder above into it. If C:\ProgramData\ssh\administrators_authorized_keys doesn’t exist then copy the authorized_keys file from your .ssh home directory (e.g c:\users\darrenjrobinson\.ssh ) to C:\ProgramData\ssh\administrators_authorized_keys
  • Edit the permission on the administrators_authorized_keys file.
    • Right-Click the file => Properties => Security => Advanced => Disable Inheritance => Choose “Convert inherited permissions into explicit permissions on this object” 
    • Remove Authenticated Users so that only System and Administrators remain as per the screen shot below. Then select Apply and then OK.

Administrators Authorized Keys.PNG

Testing SSH with Key Access

From our Azure Cloud Shell SSH to your Windows 10 Host;

ssh username@ipaddress

SSH Key Access.PNG

You will be prompted for the passphrase you gave when you generated the SSH key. Enter that and you will be authenticated using SSH to the Windows 10 VM.

SSH to Windows 10.PNG

Docker Access from Azure Cloud Shell in Browser

Now that we have Privileged Access to our Windows 10 VM, let’s try running a Windows 10 1809 Container and executing a PowerShell command to query the version of PowerShell available.

docker run -it mcr.microsoft.com/windows:1809 powershell $psversiontable

Run Docker.PNG

Wait a few seconds (maybe longer depending on the spec of your VM) and

PowerShell Desktop via Docker.PNG

Fantastic, we have a Container with PowerShell Desktop that we have accessed via Cloud Shell in a Browser.

Docker Access from Azure Cloud Shell in iOS Azure App

Using the Azure iOS App on my iPhone I started a Cloud Shell session and changed to my home directory cd ~\ where I had put a file named Connect-Win10.ps1 which contains

ssh username@ipaddressOfWin10Host

IMG-8441

I executed it and it prompted me for the passphrase for my SSH Key which I entered

IMG-8444

and I was then SSH’d into the Windows 10 VM.

IMG-8445

I did a dir d* and saw the DockerPS.cmd file I’d previously created. It contains the following command.

docker run -it mcr.microsoft.com/windows:1809 powershell $psversiontable

IMG-8446

Running that file

IMG-8447

starts the Docker Windows 1809 Container with the PowerShell command

IMG-8448

and I can see from my phone I’m have access to a PowerShell Desktop via Azure Cloud Shell and Docker from inside a Windows 10 VM based in Azure.

IMG-8449

Summary

This post has demonstrated that it is possible to get an elevated privileged session into a Windows 10 host using SSH, from which Docker Containers can be orchestrated and executed. By doing this from Azure Cloud Shell, it means that I can essentially login to a browser or app from anywhere in the world and access my Virtual PowerShell environments that in turn will allow world domination. Muwahahahah.

Got thoughts or feedback on this? Twitter || Blog

Nested Virtual PowerShell Desktop Environments on Windows 10 & Windows Server 2019 in Azure – Part 1

22 Nov 18 Part 2 is available here that details accessing
the Docker Image via Azure Cloud Shell / SSH
27 Nov 18 Part 3 is available here that details customizing
an image and accessing it via other SSH clients with 
elevated access.

PowerShell Desktop Virtual Environments

If you’ve been working with PowerShell for any length of time you know that through its flexibility there can come challenges when using disparate PowerShell Modules and often their version dependencies. This isn’t just a PowerShell thing; Python can also trip you up in a similar manner.

Python however has Virtual Environments (virtualenv) capabilities which provides functionality to create an environment that contains all the necessary binaries required for the packages/libraries that a Python project would need. I’ve found this this very useful and I’ve wondered why I couldn’t do the same for PowerShell Desktop (not Core). PowerShell Desktop, PowerShell Core?

PowerShell Desktop vs PowerShell Core

As of August 2016 there are two PowerShell versions;

  • PowerShell Desktop
    • PowerShell 5.1 that runs on Windows and on top of the full .NET Framework stack
  • PowerShell Core
    • PowerShell Core 6.x that is cross platform (Windows, MacOSX, Linux)
      • Doesn’t run on the full .NET Framework

If you are a Windows/Directory Services Admin the likelihood of many of the PowerShell Modules you use running on PowerShell Core are slim. That’s because a lot of the modules you use require the full .NET Framework. And that isn’t available in PowerShell Core.

A Virtual PowerShell Desktop Env? Why is this only possible now?

In July this year Microsoft started providing Windows Container Images for the Insider releases (over and above Nano and Core OS builds). This was great, but meant you needed to be on the Insider Builds and were restricted to environments on physical hardware or VM’s migrated to Azure as there wasn’t an Azure Marketplace OS Version (Windows 10 or Server 2019 Preview) that met the minimum host requirements for the Insider Container images.

We’ve had to wait until Build 1809 became available in the Azure Marketplace which it did at the end of last week (w/e 18 November 2018). The Windows Container Version History shows that there was no 1803 Windows Image. But that’s all bygones now, as 1809 is finally here.

PowerShell Desktop Virtual Environments through Nested Virtualization

The screenshot below on first glance just looks like any command window in a virtual machine. But look a little closer;

  • Remote Desktop Session to an Azure Windows 10 1809 Virtual Machine (host.region.cloudapp.azure.com)
  • Docker Run Windows 1809 PowerShell $psversiontable
    • PowerShell Desktop 5.1 via Docker inside a Virtual Machine in Azure
      • BOOM!!

PowerShell Desktop Virt Env Nested Virtualization.PNG

Ok, so that is a single Docker Container with a full Windows 10 1809 environment running inside a Windows 10 Virtual Machine. But that means we can also add more containers and have multiple isolated PowerShell environments. Something like ….

Nested Virtual PowerShell Desktop Env.png

Wait, what, how? – The Overview

The high-level process is;

  • Provision a Windows 10 Virtual Machine (Build 1809 or later).
    • I recommend to deploy it in Azure, but you could do it in other virtualization environments that support Nested Virtualization
    • NOTE: As I write this Windows Server 2019 Build 1809 hasn’t hit the Azure Marketplace. When it does, as it has a common code-base it should work exactly the same.
  • Enable the OpenSSH Feature (I’ll be using this a little in this post but more in a future post)
  • Enable the Containers and Hyper-V Features
  • Install and configure Docker
  • Pull the Windows Build 1809 Container Image

Windows 10 Build 1809 Virtual Machine

I’m not going to give step-by-step details for deploying a Windows VM in Azure. If you’re looking to setup Virtual PowerShell Desktop Environments with Docker you should be able to deploy a Windows VM. That said you need to choose a VM Size and Version that will support “Nested Virtualization”. The Azure RM Dv3 and Ev3 Series VM’s do. If you get an error similar to this when running a Docker Image then change your VM Series to Dv3. I went with;

  • The Azure Marketplace has a image for Windows 10 Build 1809. Search for Windows 10 Pro, Version 1809
    • In order to run this VM as pragmatic as practical I chose the following size and configuration for my VM initially
      • Standard D2_v3 (2 vCPUs, 8 GB memory)
      • HDD over SSD
      • Un-managed disks
    • Enable SSH and RDP in the NSG configuration
      • initially we’ll need RDP to connect to the workstation
      • moving forward we’ll be using SSH

OpenSSH Server

OpenSSH Client and Server has been available for Windows for a while. Build 1809 though has streamlined the install process considerably. The base install and setup is now just a couple of commands away. The commands below will install the latest version of OpenSSH Server via PowerShell;

# Find OpenSSH Server
$openSSH = Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

# Install OpenSSH Server
$sshServer = $openSSH | Select-Object name | Where-Object {$_.name -like "OpenSSH.Server*"}
$sshServer

Add-WindowsCapability -Online -Name $sshServer.Name

which when executed via VSCode looks like;

Install OpenSSH Server on Windows 10.PNG

By default the SSH Server service is configured for Manual startup. To configure it for Automatic Startup use the Set-Service cmdlet.

# Set SSH Server for Auto Startup
Get-Service sshd
Set-service sshd -StartupType Automatic

ssh Server Startup Automatic.PNG

Finally we need to increase the ClientAliveInterval setting in the sshd_config configuration file located in the %programdata%\ssh directory. I’ve made mine 3600 seconds (1 hour).

sshd ClientAliveInterval.PNG

Windows Containers / Docker Dependencies

# Install Containers / Docker Dependencies
Enable-WindowsOptionalFeature -Online -FeatureName containers –All -NoRestart
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V –All
Restart the computer

Install Docker

Head on over to Docker and login (or create an account if you don’t already have one). Get Docker CE for Windows. I’m running 18.06.1-ce-win73.

Download and Install Docker.PNG

As we want a full Windows environment for PowerShell (not PowerShell Core on Linux) select “Use Windows containers” when installing Docker.

Use Windows Containers.PNG

At the end of the Docker install there is a reboot required.

Docker Install Complete.PNG

Get the Windows 1809 Base Container Image

We’re almost there. We need to get the recently released full Windows Image that will be the basis for our containers that will allow us to run full PowerShell environments. Don’t be confused by the Nano and Core images that have been available for quite some time. This is the FULL WINDOWS Build 1809 IMAGE.

As future Windows updates increment the version, the version you want to pull needs to be no greater than the host it is running on. Unlike the Insider Images the release versions follow the Release Number not the Build Number. Looking at the repository we can see that the image name is 1809 where-as its Build Number is 10.0.17763.134.

Docker Windows Image Registry.PNG

With the workstation restarted we SSH into it and pull the Windows 1809 Docker Image. I’ve given my Windows 10 VM a DNS name so I don’t need to figure out the IP Address each time I start it up. From a Windows command prompt to access your new VM (via IPAddress) use;

ssh username@IPAddressofWin10VM

Once we have a console on our Windows 10 VM we can pull the Windows 10 Docker Image.

docker pull mcr.microsoft.com/windows:1809

The image will be retrieved.

Pull Windows 1809 Base Image.PNG

After pulling the image it will be extracted. Depending on the spec of your VM this may take 10-20 minutes.

Extracting Windows Base Docker Image.PNG

After Extraction we have our base Container Image.

Completed Docker Image.PNG

In order to create a container from the command console via SSH we need to be elevated. I’ll cover that in the next post. So to validate we are able to create a container based on the full Windows 10 1809 image, RDP into the Windows 10 VM and open an elevated command prompt. Then type the command;

docker run -it mcr.microsoft.com/windows:1809 powershell $psversiontable

which will start a container using the Windows 10 1809 Image and run PowerShell with the command $PSVersionTable that will return the version of PowerShell.

PowerShell Desktop Virt Env Nested Virtualization

Summary

As you can see from the screenshot above, we have Nested Virtualization in an Azure Resource Manager Windows 10 Virtual Machine running a Docker Windows 10 1089 Container Image that allows us to run PowerShell Desktop 5.1. BOOM!!

That’s it for the first post, where I introduced the concept of Full Windows Docker Images supporting PowerShell Desktop in Azure. Stay tuned for the next post that starts putting this new functionality to good use.

Got thoughts or feedback on this? Twitter || Blog

Retrieving SailPoint IdentityNow Certification Reports using PowerShell

This is the third and probably last post in the Certifications by API series. The first post detailed retrieving and searching campaigns, the second post detailed creating and starting campaigns. If you haven’t read those, check them out as they will give you the background for this one.

As detailed in the previous two posts this post also assumes you are authenticated to IdentityNow as detailed in this post, and you understand that this post details accessing Certifications using the non-versioned SailPoint IdentityNow API’s.

With that all said, this post details obtaining Certification Reports from Completed Campaigns. The process goes like this;

  • Search and return Completed Campaigns
  • Identify campaigns completed within a time period
  • Retrieve and export the CSV completion reports

Note: The first time you access the getReports API for a Campaign the Reports are automatically generated. You can and should include additional logic to catch that the request for the report fails and wait a minute before retrying when the report has been generated allowing you to then retrieve it.

Reports API

As mentioned above the getReports API is used to get a list of reports from campaigns.

https://$($orgName).api.identitynow.com/cc/api/campaign/getReports

To get an individual report the report/get API call is used along with the ID of the report to retrieve. The base URI is;

https://$($orgName).api.identitynow.com/cc/api/report/get

Exporting Certification Campaign Completion Reports

The following PowerShell script will enumerate completed campaigns, compare the completion time to the current time and the time window to export (last 7 days in my example below) and export the CSV version of the reports to a directory on the host running the script.

Update:

  • Line 11 for the number of days previous to days date to retrieve reports on
  • Line 34 for the output CSV path. The exports are named based on the Description of the Campaign, so you’ll need to modify that if all your descriptions are the same

The output is the CSV File which can then be manipulated in PowerShell or Excel (via Data => Import CSV.

Certification Report in Excel.PNG

Summary

Using the Certifications API we can query for Completed Certification Campaigns and then retrieve their complete reports and export them to the file system. Likewise with a few simple changes you can also export the other reports.

PowerShell Progress Notifications that work in Visual Studio Code on Window 10

Earlier this year I made the switch from PowerShell ISE to Visual Studio Code (VSCode) and everything has been going just swimmingly. Well, until I was modifying some old scripts that perform some long running processes and I’d previously added Write-Progress statements in them to provide feedback as to how the script was going. Long story short, Write-Progress doesn’t work in VSCode. I’m definitely not the first to notice this as there is an open issue on Github for it, but seeing as its been open for 2 1/2 years I figured it probably wasn’t going to be resolved soon.

So I went looking for alternatives. I’ve found two that I’m happy with and will be using moving forward. One is a text-based console output progress bar and the other uses Windows 10/Windows Server Notification Centre. This post explores both and how I’m using them.

psInlineProgress

psInlineProgress is authored by Øyvind Kallstad and has been around for a few years now, so does require a small tweak to get it to work with VSCode. Nothing major, just a change for the Console (details further below). The progress bar itself is similar to the Write-Progress one in PowerShell. Here is an example;

inLineProgress Bar Notification
inLineProgress Bar Notification

You can get it from here if you need a manual install, otherwise it’s quick to install via Install-Module

Install-Module -Name psInlineProgress

To allow the progress bar to display in VSCode update the psInlineProgress.psd1 file to change Line 36 as shown below. You should be able to find it in C:\Program Files\WindowsPowerShell\Modules\psInlineProgress\1.1

#PowerShellHostName = 'ConsoleHost'
PowerShellHostName = 'Visual Studio Code Host'

Outputting to psInlineProgress

Updating the psInlineProgress bar is simply a case of giving the Progress Bar the dialog text you want displayed, in percent the progress, the progressed and un-progressed characters. In my example above I’m using the < symbol for the progress position, for the un-progressed and . for the progressed.  Sort of like a Pac-Man consuming dashes and outputting periods.

The PowerShell line looks like this, where $percentComplete is an integer between 0 and 100. E.g

Write-InlineProgress -Activity "Getting User Object $($obj.displayName)" -PercentComplete $percentComplete -ProgressCharacter '<' -ProgressFillCharacter '.' -ProgressFill '-'

Burnt Toast

Burnt Toast is a newer module writen by Josh King that takes advantage of new features in Windows 10. The progress notification isn’t a progress bar, but a Toast Notification via the Notification Centre. Here is an example;

Burnt Toast PowerShell Notification
Burnt Toast PowerShell Notification

You can get it from here if you need a manual install, otherwise it’s quick to install via Install-Module

Install-Module -Name BurntToast

Outputting to Burnt Toast

Updating Burnt Toast is similar to inlineProgress whereby you pass dialog text you want displayed, the progress completed as a fraction between 0 and 1, and a graphic. E.g

$ProgressBar = New-BTProgressBar -Status 'Getting User Objects' -Value $progressDisplay
New-BurntToastNotification –Text ‘IdentityNow Source Import’ -ProgressBar $ProgressBar -Silent –UniqueIdentifier 'Get Users' -AppLogo "C:\Users\DarrenJRobinson\Images\sailpoint.png"

As Burned Toast is a Windows Notification, after the toast notification disappears it can still be found in the Notification Centre.

Windows Notification Centre - Burned Toast
Windows Notification Centre – Burned Toast

Other Burnt Toast Features

Burnt Toast can do much more, such as Alarms, Sounds and Reminders. See examples for those and more on Github here.

Working Example

Here is a working sample from a project where I’m processing thousands of identities. The $idnObjects is a PowerShell Object Collection of all the identities.

The following script snippet comes from the processing loop that processes the identities. $i is incremented on each loop (e.g $i++) and then used to calculate the percentage and fraction completed.

psInlineProgress and Burnt Toast are only updated each whole % of progress (that is calculated in line 9).

The output in VSCode therefore looks like the following. In reality you’d only have one or the other depending on what you were looking to achieve. I’ve done both together to show a side by side comparison.

Toast and Progress Bar.PNG

Summary

Goodbye Write-Progress and Hello Burnt Toast and psInlineProgress