Controlling your Azure Automation runbooks with Git and Azure DevOps (My PowerShell Journey through Azure DevOps – Part 1.5)

Part 1: My PowerShell Journey through Azure DevOps – Part 1

As I said in Part 1, I started down the paths of pipelines by copying some people that were using AppVeyor. AppVeyor does appear to have a set of tasks for building, testing, releasing etc, though for better or worse, the examples I found put must of the work into a PowerShell script and just used AppVeyor to execute that script, instead of parceling out build and test and deploy tasks directly.

With that as my influence, while I was still working on deployment for our modules, I also started looking at testing and deploying our Azure Automation runbooks through Azure DevOps. The old way was an Azure Automation runbook that would deploy any file that got committed to master of our runbook repository in GitHub. The new way uses Azure DevOps to run tests, do some kind of actual building, deploy to a test environment, and finally deploy to production. None of this was possible with our old system.

If you’ve never used Azure Automation this might not all make sense. Since this isn’t strictly about PowerShell modules I’ve labelled this Part 1.5, maybe think of it as bonus content. I would someday like to write more about how we’re using Azure Automation, and hopefully that future post can put this one in a little bit of context.

I’ve also made my code available on GitHub for anyone to look at. I’ll explain the repo a bit at the end but first here’s 2500 words explaining myself.

The problem statement

Continue reading “Controlling your Azure Automation runbooks with Git and Azure DevOps (My PowerShell Journey through Azure DevOps – Part 1.5)”

My PowerShell Journey through Azure DevOps – Part 1

Back in March of this year I decided I was unhappy with our PowerShell module deployment process. We have a number of open source PowerShell modules of varying quality that we’ve written to solve some need of ours. Most of them are providing interfaces to consume REST APIs in some kind of task based way. We have no automated testing, no real build process, and our deployment process is just an Azure Automation runbook that copies files whenever there’s a commit to master (plus a push to the PowerShell Gallery). A number of things came together back in March where I started learning about Pester testing and these things called Pipelines.

Continue reading “My PowerShell Journey through Azure DevOps – Part 1”

Syntax checking your Powershell code with Pester

If you just want to syntax check your Powershell code with Pester, scroll to the bottom and grab my describe block. If you’d like you’d like to go on a little journey with me, keep reading.

I’m in the process of getting as much of team’s Powershell code through a CI pipeline using Azure DevOps. Due to some issues with accidentally pushing code with syntax and encoding errors to production, one of the first things I wanted to do was just simply validate that the code was valid. I found a post on the forums from 2014 that inspired me to write this test:

Continue reading “Syntax checking your Powershell code with Pester”

Finding a Specific Setting in your Client Settings

With ConfigMgr 1806, the Application Catalog service and site roles are no longer needed, so for me it was a good opportunity to have 2 less servers to care and feed for. But because I was a dummy, in Default Client Settings I had selected my app catalog site explicitly rather than letting the client automatically pick (I have no idea why I did this). And when you make a new client setting, it inherits the settings of the default, so anyone who made a custom policy with Computer Agent had that setting. This setting being defined prevents the removal of the application catalog roles.

I have 41 Client Settings, I’m not about to look through each of them for Computer Agent settings. So Powershell to the rescue. Get-CMClientSetting will get you a list of all your Client Settings, but there won’t be any information on them. There’s a -Setting which will return all the settings of the specified type, but as it turns out, nothing to tell you which Client Setting contains that setting. So it turns out, you have to get every Client Setting, and interrogate it if it has the Computer Agent setting. With this code I was able to find the five Settings that had Computer Agent specified, and change the Default Application Catalog website point.

$allsettings = Get-CMClientSetting | select -ExpandProperty Name
foreach ($name in $allsettings) {
    if (Get-CMClientSetting -Setting ComputerAgent -Name $name) {
        write-host $name

I could have gone farther with this, as the object returned will have a PortalURL property, but merely listing the Settings that had Computer Agent was sufficient for this. This could be generalized to look for any Client Setting with a particular setting, and further to look for specific values if needed.

RBA and New Boot Media

This is a pretty simple one, but I love when solutions to problem I’m having with ConfigMgr Current Branch are the same (and thus the same solutions) as people using ConfigMgr 2007 (this seems to be a recurring trend with me).

I was creating new boot media using the New-CMBootableMedia cmdlet, and getting this error message:

New-CMBootableMedia : Create media exited with an error: -2147217407 (0x80041001)

If I tried to use the console I got this error:

Media creation failed with error code -2147217407.

Refer to CreateTsMedia.log file to find more details.

Checking CreateTsMedia.log (this file is created on the system where you’re creating the media from, at something like C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\AdminUILog\CreateTsMedia.log) I see this block of red text:

Staging certificate

Error invoking WMI method SMS_Site.SubmitRegistrationRecord (0x80041001)

StageCertificate::Register() failed. 0x80041001

Error executing state StageCertificate

Error executing first single pass

Failed to create media (0x80041001)

CreateTsMedia failed with error 0x80041001, details=''

CMtrace helpfully informs me that 0x80041001 is Generic Error, so things aren’t looking good.  After some Googling I come across someone with what sounds like the same error as me, except they’re having it with 2007, not 2012/CB.  But they did have a solution

My problem has been solved.  The SMS Admins group did not have “Import computer entry” and “Manager OSD and ISV Proxy Certificates” rights.

Well crap, the 2007/2012 permissions model is completely different, but I am running this as an account that doesn’t have the Full Administrator role, so let’s see what we can find.  I already had the “Import Computers” permission, under the Site node, but right below also in the Site node it was “Manage Certificates for Operating System Deployment” set to No.  Switch that to yes and give it another try, the boot media is successfully created!

Certificates would appear to be “scopeless” here.  Normally something at a system level without a scope belongs to the Default scope, but my account doesn’t have any roles applied to the Default scope, so it would appear that granting that permission is sufficient regardless of what scope the role is applied to.

Managing Multiple ConfigMgr Sites with Powershell

We’re in the middle of migrating from a single ConfigMgr site to having two separate sites for servers and desktops.  Along with test sites, that’s a lot of sites to manage!  When you’re running Powershell on a machine that is managed by a site, you can easily cd, set-location, or push-location to that site’s drive. But what if you want to manage a site different than what’s managing your machine?  You can open a powershell terminal or ISE session directly from the console, but that can be a hassle, and also won’t work for things not run interactively.  I’ve taken to putting this code at the top of all of my scripts.

Continue reading “Managing Multiple ConfigMgr Sites with Powershell”

CIS Server Hardening and ConfigMgr

I recently worked on hardening an ConfigMgr Environment, using the CIS Windows Server 2016 Hardening Benchmarks.  We’re a CIS member so I have access to the GPO template, so after reading through the benchmark document, I removed the few settings I knew I didn’t want.

After applying this policy to my site systems, clients were no longer showing activity in the console, and they’d lost their green check mark.  I traced the path of a hardware inventory from one client, and it was able to successfully send the inventory to the management point, but it still wasn’t updating in the console.  I cranked up logging on the management point, and looked in mpfdm.log.  The log was full of errors like this:

**ERROR: Cannot connect to the inbox source, sleep 30 seconds and try again.

Occasionally I also had this error:

CFileDispMgr::GetStagingLocation(\) failed with 0X80070057
Continue reading “CIS Server Hardening and ConfigMgr”