Audit Script related activities in Configuration Manager

A few hours ago, I just posted my auditing POC solution for Configuration Manager, and that solution also integrates with Log Analytics and Azure Sentinel.

In Configuration Manager, we can add Scripts, and if the Script is approved, we can execute these against a specific device or many devices or a specific Collection. These scripts run in real-time. If the client is online, it’s going to run the Script.

We also know that administrators copy and paste many scripts from the internet, and they may also enter different credentials there, etc. All the usual stuff and nothing special 😊

AZMEMCM allows you to capture all script executions, and we can capture the script content as well. Let me show you.

To add the Script in Configuration Manager, follow the following steps:

  • Open Configuration Manager admin console
  • Browse Software Library -> Scripts
  • Choose Create Script

After that, approve the Script, and now we can execute the Script against our devices or Collections. Let’s run the Script against All Systems 😊

Right-click All Systems and select Run Script

Select the Script that we downloaded from the Internet

Click Next and Finish the wizard

Go back to Scripts and delete the Script

What can we see from the logs?

From the Log Analytics side, we should see the following events:

  • 52500 new script
  • 52501 script approved
  • 40805 script execution against the Collection

Screenshot from the Log Analytics portal.

One additional query also shows us the ScriptContent, and it is the encoded value from the Configuration Manager. We can copy the ScriptContent value to PowerShell, and we can convert the encoded value to the real Script.

In PowerShell, we can do it like this:


Please remember that this is a POC solution –

Have fun!

Configuration Manager and Azure Sentinel

A few months ago, Microsoft had an Azure Sentinel hackathon, and I thought that maybe I could build-up one POC solution for Azure Sentinel. My idea was to capture all the admin activities and send the data immediately off the Primary Site server. The reason why I decided to build this POC is that the built-in auditing isn’t that good, and it needs some modernization.

You can download all the scripts and manuals from my GitHub account –

If you have any questions, then just let me know.

Have fun!


Get-ChildItem and Configuration Manager PowerShell Provider

This week I had the opportunity to speak at the Midwest Management Summit. This year I had two different sessions together with Ryan and Mike. With Ryan, we talked about automation capabilities in Configuration Manager.

Get-ChildItem is one of the cmdlets that you have used in PowerShell. On file system Get-ChildItem prints out files and folders, if you run the same cmdlet against the certificate store, then it prints out the certificates, etc. However, if you take the Get-Childitem cmdlet and you run it inside the Configuration Manager PowerShell provider, it only prints out the admin console folders but not the objects within that folder.

Get-ChildItem and Configuration Manager PowerShell Provider

Now you may have a question how can I get applications, collections or packages from a specific folder? If you are using folders like me, then sometimes you may need to change objects under a particular folder and not all the objects.

Luckily we have two different workarounds, and in both cases, we need to retrieve the objects directly through WMI using WMI cmdlets in PowerShell. So let’s take a closer look at how to do that.

Option 1

Here is the sample folder structure that we are going to work. In this case, we have one application under the Dell folder. In a production environment, of course, you may have multiple objects under one folder. However, for the demo purposes, we keep this simple.

So the first step for us is to identify the ContainerNodeID value. ContainerNodeID is the unique folder ID. To do that we need to use the following command:

This command returns the following output:

From this output, we need to copy out the ContainerNodeID property value, and we are going to use that in a WMI query.

Change the FolderID and SiteCode variable values and then execute. This code block should produce the following output:

As you see now, we have the Dell Command Monitor 2 application information in our PowerShell session. So let’s try to change the application name to something else using Configuration Manager PowerShell module cmdlets.

Set-CMApplication cmdlet failed because the object type is different. Object type must be Microsoft.ConfigurationManagement.ManagementProvider.IResultObject.

To fix this issue, we need to use ConvertTo-CMIResultObject cmdlet. This cmdlet allows us to convert WMI instance to Microsoft.ConfigurationManagement.ManagementProvider.IResultObject.

Yep, you heard it correctly. This cmdlet is awesome 🙂

So let’s run the following code block and see what happens

Now check the Dell folder in your Configuration Manager console.

Option 2

In this example, we are using the same folder structure, but the code will be a little bit different.

Let’s run the following code block:

In this example, I’m reading the data directly from SMS_ApplicationLatest WMI class. In that class, we have ObjectPath property, and that property holds the full path to object. We can do the same with Collections, Packages etc.

Have fun!

How to configure Azure Automation Visual Studio Code Extension

In this post, we will configure the Azure Automation Visual Studio Code extension. For a long time I used to use Azure Automation PowerShell ISE extension, and last week I decided to test out the Azure Automation Visual Studio Code extension.

So before you can configure the Visual Studio Code extension, we need to set up the Azure AD Application.

Azure AD Application configuration

  1. Open Azure Portal –
  2. Select Azure Active Directory and choose App Registrations.
  3. Select + New Application Registration.
  4. Fill out the details:
    1. Name: Azure Automation Runbook Manager
    2. Application Type: Web app / API
    3. Sign-on URL:
  5. Click Create.
  6. Copy Application ID to NotePad.
  7. Click Settings and choose Keys.
  8. Fill out the Key description, duration and click Save.
  9. Copy key value to NotePad.
  10. Close the Azure AD Application configuration panels and go back to the main Azure AD configuration panel.
  11. Select Properties and copy the Directory ID to NotePad.

Visual Studio Code configuration

  1. Select Manage and choose Settings

  2. Expand Extensions and choose Azure Automation

  3. Fill out the following information:
    1. Automation Account: Azure Automation Account name
    2. Client ID: Azure AD Application ID
    3. Client Secret: Azure AD Application Keys value
    4. Resource Group: Azure Automation Resource Group Name
    5. Subscription ID: Your Azure subscription where you have the Azure Automation Account.
    6. Tenant ID: Azure AD Tenant ID
  4. Close the Settings
  5. Select the Automation Explorer

  6. Click + and fill out the Runbook name.

Azure Automation Account configuration

    1. On your Azure Automation Account assign the Contributer permissions for the Azure Automation Runbook Manager Azure AD Application.


If everything went correctly, then you should be able to create Azure Automation Runbooks directly from Visual Studio Code.

Have fun!

My version of Jason Sandys Per User Login Message solution

You can read Jason Sandys original post about configuring Per User Login Message

In this blog post, we are going to take a different approach to configure it. Jason Sandys configured the notifications through the registry and I didn’t like that approach. It works perfectly without any issues, but I wanted to have everything in PowerShell 😊

Secondly what if, the user logged on and saw the message and went away again. When the user comes back and unlocks the workstation again, then, of course, the user doesn’t get that message anymore (in this case I assume that no reboot yet).

So, in this solution user gets notifications in two different cases:

  • At log on
  • On Workstation unlock

This solution is using built-in Scheduled Tasks

Steps to configure it

  1. Create a folder in your source repository, for example, KJ Windows 10 Upgrade Notification v02.
  2. Create a subfolder in KJ Windows 10 Upgrade Notification v02 called Content.
  3. Download Configure-KJW10UserNotification.ps1 and W10Notification.xml from my GitHub repository and place both file under KJ Windows 10 Upgrade Notification v02 folder.
  4. Download UpgradeInProgress.xml from my GitHub repository and place it inside the Content folder.
  5. Download Invoke-KJUserNotifcation.ps1 from my GitHub repository and place it inside the Content folder.
  6. Download Jason Sandys UI++ and make sure that UI++64.exe is inside the Content folder.
  7. Download Windows 10 and STOP images from Google and place them inside the Content folder.

After these steps you should have:

  • KJ Windows 10 Upgrade Notification v02 (root folder)
    • W10Notification.xml
    • Configure-KJW10UserNotification.ps1
      • Content (subfolder)
        • Invoke-KJUserNotifcation.ps1
        • STOP.png
        • UI++64.exe
        • UpgradeInProgress.xml
        • Windows10.png

Root folder

Content folder

Currently in this solution, I do except that all files will be placed under C:\Program Files\KJ Windows 10 Upgrade Notification folder. If you want to copy the files to another folder, then make sure that you change the addresses in W10Notification.xml and UpgradeInProgress.xml.

If your files are OK, then run the following command to create the Package in Configuration Manager

  • New-CMPackage -Name “KJ Windows 10 Upgrade Notification” -Path “\\cm01\sources\OSD\Packages\KJ Windows 10 Upgrade Notification v02”

Task Sequence configuration

Now create a new test Task Sequence and add the following steps

  • Add


  • Remove

Now deploy the Task Sequence to your test machine. After the successful test deployment, you should have one Scheduled Task, called KJ – Windows 10 In-Place Upgrade Notification

Content folder files under Program Files


Now lock and unlock your test workstation and you should see Jason Sandys UI++ message.

Have fun 😊

Microsoft MVP 2018 – 2019

I received a letter from Microsoft on 1st of july that I have received yet another MVP title for developing a local IT community. This is my 8th MVP title. Years ago I begun as a Configuration Manager MVP and from then on as Enterprise Client Management and by today in Enterprise Mobility category.


Create 7-ZIP Application using PowerShell

This month somebody discovered a vulnerability in 7-Zip that could allow for arbitrary code execution. Latest version download count is much much higher than previous versions. Current download count over 15.000 downloads.

If you are using Configuration Manager for deploying software, then you can easily automate such kind of activities in your environment. I have posted sample template on my GitHub repository –

Convert Group Policies into Configuration Items using PowerShell

Yesterday I posted on my GitHub repository one POC solution, that allows you to convert Group Policies into Configuration Items automatically.

I have tested this solution with Credential Guard, Microsoft LAPS, Windows Update group policy settings.

If you run the script against one of these policies or all of them you will end up with these Configuration Items in Configuration Manager.

You can download the code from here –

If you have questions or feedback, then just post a comment.

CM12SDK.NET is dead

A few months ago I took down one of my Configuration Manager and PowerShell sites called CM12SDK.NET. Back in the old days we didn’t have official PowerShell cmdlets for Configuration Manager and zero PowerShell stuff in SDK. That was one of the reasons why I built that site.

Now that we have quite good PowerShell support in Configuration Manager, I didn’t see any point to continue that site.

I moved everything over to GitHub and you can still access the old samples –