Configuration Manager Technical Preview 1706 was just recently released, this time with an exceptional number of new features to dig into. One that I’ve been eagerly waiting for, and very excited about, is the capability to in near real-time execute a PowerShell script on clients and get the result sent back to the console for processing. Before we dig into this feature, if you haven’t already read the announcement for Configuration Manager 1706 Technical Preview, have a read here:
Some history before we begin
Back in November 2016, when I was at my first MVP Summit in Redmond, all Enterprise Mobility MVP’s had the great opportunity to sit down with developers from the Product Group in a hackathon. During this time, a lot of great ideas was born and worked on, and especially one that has now seen the first dawn of light. I’m talking about the possibility to run a script on any device managed in your environment by ConfigMgr, almost in real time.
What and why
So, you might think that this is not really new, but then you’re wrong. Sure, there are many parts of the product where you can leverage PowerShell for various purposes, but this new feature is something else. Think about writing a few scripts for various purposes like fixing a faulty registry value, or starting a service. Whatever you can come up with that needs to be executed, you can do that with PowerShell on any or all of your managed devices (that has the ConfigMgr client installed). And the best part, it will execute almost immediately after you’ve set the script to run on your clients, no manual deployment required. This shows the commitment from Microsoft again, that they’re investing heavily in transforming the “Slow Moving Software” product into a more real-time friendly product. David James (@djammmer) have numerous times said that his intent is that everything in the product eventually will leverage the different fast channels available. This new run a script feature proves that and it’s exciting times for Configuration Manager admins.
What we currently have in Configuration Manager 1706 Technical Preview is an early early preview of the feature. With the currently implementation we can basically create a new script item and manually deploy (run) it on selected device collections. See more below for a list of the current implementation of the feature:
- Run script on device collections only, not able to target single devices as of now
- Existing scripts cannot be changed or removed
- Script authors can approve their own scripts for deployment
- Hierarchy setting for allowing approval of scripts
- Monitoring script execution status and output
Ryan Ephing (famous for his awesome scripts and right-click tools) has written a nice blog post regarding this new feature and what it could be used for, and I really like the idea behind it. He talks about the future of Right Click tools and how this new feature allows for a single right-click to run a script on a collection of clients and almost instantly get the script execution results back. Think about it, you don’t have to create console extensions anymore, instead you can simply run the script directly from the ConfigMgr console.
You may be wondering, what else can I do with this? Scripts that do the same as the old right-click tools would, sure that’s excellent, but think bigger. This feature could for instance be used to perform any type of tasks in your environment, such as:
- Client maintenance (change or increase client cache size)
- Operating System maintenance in terms of e.g. registry changes and feature installation/removal
- Send notifications to your clients that are online (build a custom WPF or Windows Forms UI)
- Restart a failed task sequence
- Trigger a script on a Status Message to perform a specific action
The use cases for this new feature is enormous and only limited to your scripting skills and imagination.
Want to leave some feedback for future improvements of this feature? Please use this UserVoice item then:
Creating and running a script on clients
Before we dig into how this feature works and what we can expect from it in the future, let’s take a look at what we’re currently able to do in this technical preview. What you’ll most likely notice first is the new “Scripts” section under the Software Library workspace.
This section provides a list of all the scripts that we’ve created with additional details about their approval status, author, version history and more. From here we can create a new script by clicking on Create Script. This takes us into the Create Script wizard where we can name our script and either write it directly or paste/import from another source.
Once we’ve finished the script wizard, the newly created script appears in the list of available scripts. Now that the scripts are imported, where are they saved? Tom Degreef has written a blog post regarding this topic as well, and has found that they’re stored in the database.
If we’d like to run this script that we’ve just created, on a set of devices, we’d first have to approve this script for execution. This is accomplished by selecting the script and clicking on Approve/Deny.
This action will start the Approve or deny script wizard with a simple choice of either approving or denying the script.
Once approved, the status will change from Waiting for approval to Approved.
With the currently implementation, like already stated, authors can approve their own scripts. This will change in the future, but it can be controlled by a hierarchical setting found under the General tab of Hierarchy Settings for the site:
With at least a single script approved, we can now run this on a device collection of our choice. This is done with a single right-click on a device collection and selecting the new option called Run Script.
Clicking Run Script opens up the Run Script wizard where we can select any of the approved scripts.
Complete the short wizard, but don’t go and get yourself a coffee like you normally would. This is being sent out directly to the clients in the selected device collection using the same fast channel for client online/offline status also known as the Client Notification channel. The selected script however is not pushed down this channel, only the ID of the selected script. Instead the ConfigMgr client pulls it down from the Management Point (unless it doesn’t already have it locally available). What’s really cool is that the client can also pull the script from any of it’s Peer Cache clients if available.
To check the status of the script execution and the output it created, there’s a new section under the Monitoring workspace called Script Status. This section will show you a detailed view of how each devices in the device collection executed the script, together with the execution state, script exit code and output returned from the script.
It’s worth mentioning that the data shown in this section was not sent back as a normal state message, instead it has taken another path through different fast channels. Script execution state and return code from the script travels back through the Client Notification channel while the script output comes back through the fast state message channel, the same channel used for time sensitive state information, like malware outbreaks. In other words, multiple fast channels are being used to cater for a near real-time experience running these scripts and getting the output/result from their execution.
Another thing worth mentioning regarding the output from the script is that everything shown in the actual PowerShell console, is returned as the output. This means that both output, verbose and errors streams are treated as a single output. Hopefully, this will change in the future so that you can only selected e.g. the output stream so that the returned output only contains the data you’re interested in.
Follow the logs
Since this new feature leverages already built-in capabilities of the fast channels, you can follow the flow of notifications being sent in the fast channel through the BGBServer.log (server side). What you’re looking for is a line that looks like this:
On the client side of things, there’s a new log called Scripts.log. In this log you’ll see details about the execution of the scripts set to run on the specific client:
With this new feature, another aspect of security is needed. During the Hackathon, Brian Mason prompted for the need of a security layer around who gets to create the script and who can run them. Microsoft is working on a RBA design that will not only be used in this instance for creating and approving scripts that are allowed to be executed in the environment, but it could also be extended into other areas, for instance the Application Model. With the current implementation of the feature of running scripts on your clients, the RBA model is not embedded. However we can see traces of it being worked on if we explore e.g. the Full Administrators permissions:
Another aspect as well is the security around how the script is being transferred to the clients. Since it’s leveraging the fast channels available, we’re talking about client to server communication, not server to client communication. This means that we don’t have to open any additional firewall ports to get this working, which is a huge advantage.
With special permissions from David James, we have been allowed to share some upcoming enhancements and new capabilities Microsoft is currently working on regarding this feature. Below is a list, not ordered by priority, of what Microsoft is working on and that we can expect in the upcoming technical preview releases:
- Support for using Parameters for your scripts
- Scheduling for scripts
- Support for PowerShell DSC
- Script revisions
- Run scripts on individual computers
- Better editor for amending/writing scripts directly from the console
This is not in any way a complete list of what Microsoft is working on, but something that we MVP’s have raised as feedback.
Bonus – Creating Scripts with PowerShell
I figured this is a post about running PowerShell scripts on clients, why not take it a step further and create the actual script that is supposed to be executed on the clients, by using PowerShell.
# Hardcoded variables for site information $SiteServer = "CORP-CMTP01" $SiteCode = "TP1" # Here-string containing the PowerShell script $ScriptCode = @" Get-Process | Select-Object -Property Name "@ # Input parameters for method execution $ScriptArgs = @($null, $null, "CORP\nickolaj", $null, $null, $ScriptCode, (([System.Guid]::NewGuid()).Guid), "Created with PowerShell", $null, $null) # Invoke CreateScripts method Invoke-WmiMethod -Namespace "root\SMS\site_$($SiteCode)" -Class SMS_Scripts -Name "CreateScripts" -ArgumentList $ScriptArgs
When the above script is executed, we’ll find a new Script inside the Scripts section called Create with PowerShell: