-
Automating Performance Monitor in Windows
This post is the first of three for automating common debugging tools on Windows endpoints.
Earlier this year I came across a scenario of an application dropping connections. This was occuring across many hundreds of users and sporadically. Typically, I would attempt to recreate the issue so I could debug, but that was not possible here. I needed a way to be ready for the drop to occur and have all debugging tools setup proactively across a large number of users.
We use ConfigMgr to run scripts on workstations from a central location and it worked well in this scenario.
Initial setup process
- In Performance Monitor (perfmon.msc), create the necessary Data Collector Set, henceforth abbreviated DCS
- Be sure to specify the directory you want your output in
- Export the DCS you created. Right-click and Save template to .xml.
- Download Start-PerfmonCapture.ps1 linked below
- Copy the contents of the .xml into below script so no artifacts are necessary outside of the script. It is self-contained.
- Add a Run Script to ConfigMgr to be ran on devices, Start-PerfmonCapture
- Add the column for Script GUID to the ConfigMgr console and copy it out
- Create collection of target devices
- Trigger the Run script each morning at a specified time on target workstations to create and start the DCS using the Invoke-CMScript cmdlet. I used Azure Automation to trigger this daily and re-run hourly to ensure the DCS was always running. You can use any automation solution you prefer
Invoke-CMScript -CollectionId <CollectionId> -ScriptGuid <scriptguid>
The script
This script is fairly basic, mostly just took figuring out how to interact with a Data Collector Set using logman.exe and make sure it didn’t clobber the existing DCS that is running.
Special thanks to Aussie Rob SQL, Jonathan Medd, and Rabi Achrafi for the example scripts I found online. References are in the script help text. Also thanks to my co-workers Darren Chinnon and Raul Colunga who helped put this together.
Script anatomy
- Populate the XML for the Data Collector Set
- Specify name of DCS
- Query if DCS already exists with specified name
- If DCS found, check if running
- If running, exit
- If not running, start it
- If DCS not found, create it and start it
Edit the lines below to personalize as needed
- Line 27 through 210 - Your custom XML
- Line 212 - DCS name
Partial Preview
$DCSName = 'PerfMonExample'
$DCSCheck = & logman query $DCSName # Query if DCS already exists
if ($DCSCheck[1] -like "*$($DCSName)") {
Write-Output 'DCS found!'
if ($DCSCheck[2] -like '*Running') {
Write-Output 'Trace running, exiting...'
} else {
Write-Output 'Trace not running, starting...'
& logman start $DCSName
}
} else {
Write-Output 'DCS not found, creating...'
# Create the Data Collector Set
$DCS = New-Object -COM Pla.DataCollectorSet
$DCS.DisplayName = $DCSName
$DCS.SetXml($DCSTemplate)
$DCS.Commit("$DCSName" , $null , 0x0003)
# Start the data collection
Write-Output 'Starting the DCS!'
$DCS.start($false)
}
Github Link: Start-PerfmonCapture.ps1
Output
The script gives a little output for validation, not much though. This is mostly for validation during testing.
Starting the script, there may be additional output from logman.exe for the initial run
Starting the script when DCS is already running
Starting the script when DCS is not running
Closing
Overall, this process worked well and met the need. It wasn’t the first time I had to use Perfmon and it won’t be the last. Up next, Wireshark.
-
Intune missing capabilities for the ConfigMgr administrator
Intune missing capabilities for the ConfigMgr administrator
Even if you haven’t been paying attention to recent development for, or lack thereof, Microsoft Configuration Manager, or to any of the threads on Twitter/X, Reddit, or any other major social media platforms, you still probably know the writing is on the wall for ConfigMgr. Nearly all focus in Contosoland has been devoted to Intune.
This post outlines my personal running list of gaps that Intune doesn’t quite cover for the seasoned ConfigMgr administrator.
My friend and banter extraordinaire, Bryan Dam, posted recently a quote that makes sense in describing this list.
#ConfigMgr gave you 250% of what you need. #Intune gives you 90%, we’ll get it to 100% … eventually.
Much of this list may be in the last 150%, but that doesn’t change a lot of organizations’ dependency on these capabilities. Make your own determination how critical these capabilities are for your organization.
Kim Oppalfens has the best write up I have seen to date of these gaps.
- Realtime scripts
- Realtime application installation
- CMPivot
- Task Sequences with Autopilot
- Custom inventory
- Flexible targeting
- Configuration baselines
- Software metering
- Customizable reporting
- Package distribution
My list includes a few more technical gaps ranging from critical to minor technical details.
Software installation
For the majority of your software installations, Intune should cover your needs. But the following requirements may pose an issue.
- Sequencing complex installs together - Need to deploy multiple installs in a certain order or tie in installs, scripts, and restarts at once? Complex installs like Citrix VDA or sometimes Windows Feature Upgrades are easily handled with ConfigMgr task sequences. No equivalent in Intune without complex PowerShell scripting.
- 30GB maximum package size - This isn’t even that new. This capability was bumped from 8GB to 30Gb around the start of 2024. This may pose an issue for things like Visual Studio, AutoCAD, SAS, and other very large applications. Your best option is to compress the install files into a .zip or .wim file and extract them at install time.
- IME runs as 32-bit not 64-bit - For the majority of software installs, this is no issue. Windows Installer is intelligent enough to install 64-bit to 64-bit, even when called from a 32-bit process. However, if you use PowerShell to wrap your installs, such as the ever popular PowerShell Application Deployment Toolkit, you have to take extra steps to trigger the process as 64-bit. Not ideal, especially if you wrap all things in PSADT.
Shared device scenarios
- Non-persistent VDI scenarios - Want to go full modern Entra ID only + Intune only? Not supported, hard stop. To be fair, most orgs are probably not using ConfigMgr on non-persistent scenarios, but they are using GPO. So going Entra ID only is a killer here. Not exactly an Intune gap, but modern endpoint as a whole.
- No maintenance windows - There are lots of uses for admin-controlled hard coded timeframes when maintenance can occur. Known as Maintenance Windows in ConfigMgr, they are very valuable for highly critical devices, shared devices, and devices running on shared infrastructure like VDI. Based on recent conversations this does seem to be top of mind for Microsoft.
Real time capabilities
- 8 hour policy check-in (ConfigRefresh is 90 minutes) - ConfigMgr, formerly known as “slow moving software” is arguably much faster than Intune. Just check Reddit for comments about Intune being slow. Simpler? Maybe, but the admin can’t exactly control when things will happen. Recent improvements to ConfigRefresh have helped here, but it still can’t beat a 60 minute policy refresh in ConfigMgr for all actions on the endpoint. What does our org do? We have a Run Script in ConfigMgr to trigger a MDM sync using the scheduled task. The forced sync from the Intune portal isn’t reliable enough and cannot be performed in bulk.
- Expire/disable deployments - It’s 11pm at night, you just deployed something to thousands of endpoints. Your helpdesk’s call volume starts to rise. Big red button time. In ConfigMgr, you never want to delete the deployment, you lose all history and record of potentially impacted devices. You instead expire or disable the deployment. In Intune, no such option. you remove the assignment and find another way to identify impacted endpoints. Can you parse the IME log, event log, Sysmon, MDE, or other means to see what occured on the endpoints locally? Sure, but that is way more complex and time consuming when leadership has you on an outage bridge asking for impacts now.
If you are a large organization, you may hit the 200 maximum remediations limit. Our organization has well over 200 ConfigMgr baselines, so we are keeping this workload in ConfigMgr for now.
Targeting
We all know that for modern endpoint management you generally want to target users, not devices. There is a lot of value targeting users, especially as Intune is designed to work better this way. However, you lose out on certain deployment abilities that ConfigMgr delivers beautifully with collections today. Good news though, coming soon to Intune is device inventory! This seems to be the first step in opening up more targeting capabilities besides Entra ID groups and virtual groups + filters.
- Targeting based off installed software - This is our most commonly used scenario. Nearly every software deployment we do follows this template. Collection of target devices excluding devices with X software installed. Build pilot groups off that collection. When your collection hits 0 you are done. It is a combination of targeting + inventory to maximize success of your software deployments. Our organization averages over 3000 software deployments a year, and every little software install success matters.
- Targeting based off installed software versions - Same logic as above, but mainly for upgrades from version X to version Y.
- Targeting based off software usage/metering - Very valuable for software audits, license reclamation, and other software lifecycle scenarios.
- Targeting based off registry keys - How many software applications do you have that store relevant info in the registry? Zscaler Private Access, Digital Guardian, lots of others. Inventory the registry keys, build a collection to target.
- Targeting based off WMI properties - We have almost 100 custom inventory items we store in WMI to solve all our targeting wildest dreams. Drivers, some user profile specific registry key, custom branding, the list goes on.
- Targeting based off management properties (domain, co-managed workload, etc) - This is mostly used for limiting deployments to relevant endpoints. Only want to target your Entra ID joined devices? Only hybrid joined? Only devices in a certain domain? All very valuable scenarios to ensure you limit exposure to devices that should not be targeted.
- Targeting null data such as software not installed - This is valuable for cleaning up your environment. Missing a required configuration or devices that should have X software installed?
- Targeting based off policies (compliant, non-compliant, success, error, etc) - If a software install fails, it will reattempt. What if you need to target a script to a device that failed to apply a config policy successfully? What if you need to apply a script to a non-compliant device?
- Targeting based off user state (user logged on, primary user set, etc) - One of the easiest ways to ensure you are not impacting an end user is if they are not logged into their device. This is great for overnight implementations and critical cleanup tasks. Being able to see the primary user of a device like with user device affinity in ConfigMgr is very valuable here. Great info for cross checking asset management systems and targeting users with multiple devices or accounts that login to multiple users devices.
Ironically, if you do need some of these dynamic capabilities for targeting you can use ConfigMgr to get them in Intune. Check out collection sync. Thanks Cristopher Alaya for the mention!
Closing
This is a lengthy list, and I have been keeping this list since we co-managed all our devices at the start of the pandemic in 2020. The good news is even just a year ago, this last had 5 more items. Many of these items are dropping off with every monthly Intune release and eventually Microsoft will get that last 10%. I personally expect co-management will still be necessary for the next 5 years though, we shall see.
-
Pretty permalinks using IIS 8/IIS 8.5
When I threw this blog together, I had chose one of the default Permalinks options of:
http://domain/index.php/%postname%
I wanted to get that index.php out of there and that is where my journey began.
I am running WordPress on IIS 8.5 and Windows Server 2012 R2. First, I just went in and attempted to edit the Permalinks under settings, but when I went to save I got the below error.
-
Blog intro
Welcome
This is my first post on my new blog. I migrated from Wordpress to Github pages with Jekyll. Just being to able to post straight from Visual Studio Code will be a pleasure.
My old blog was self-hosted on Wordpress, via potentengineer.com.
-Daniel