Powershell Reporting – Server Auditing – Part 1 -Getting the XML

At my current workplace every single time we install a server (yes Desired State Configuration has not caught on here yet….)there is a compliance check list that has to be filled out a to make sure that everything has been done.

I had to do the checks one time and thought it was an opportunity for something that I could automate as it was merely retrieving some information from the system itself. Besides it was taking forever to go ahead and tick some boxes.

The information that they asked for is a lot of wmi/cim information such as disk drive information, network information, operating system details and after I talked to my team leader we got it to retrieve information from group policy/SCOM/SCCM.

I was a bit new to this so after looking around powershell help, and then after looking for some inspiration   I came across Irwin Strachan post on how to create Active Directory snapshots and his other post on how to do reporting using Pscribo by Iain Brighton.

I decided to look into this further and adapt his idea of snapshots and adapt it to my problem. Thanks Irwin!

Irwin’s solution is to create variables and get the information from Active Directory and then export the information to a XML file which can then be passed through to whatever you want. . . Pester and in this case PScribo.

PScribo is a framework that allows me to the same cmdlets to produce various different types of output.

I faced a bit of challenges in regards to this. First off, the firewall ports between networks had blocked off WMI. This meant that all my Windows 2008 R2 machines were not able to be queried because the  Windows 2008 R2 machines had only Powershell V2. By default remoting was  turned off. The organisation was not keen in turning them on…it would mean changes management controls would get in the way. This didn’t really matter as there was a Windows 2012 R2 /2016  upgrade path which was in the early phases which meant that I could write my script to handle situations for future/existing versions of Windows 2012 R2.

I decided to go with the use of switches in my parameters. Due to the current limitations I thought that for every Windows 2008 R2 machine we’ll have to do the old way and copy it into the machine and then do it locally. I would have to add in the functions that I need to use for those times when I am reporting on a Windows 2008 R2 machine. I’ll use a switch -local that would tell the script to use certain methods to do things….as  some of my code did not work in a certain way. Below I’ll go over a sample of code so that you get the idea of how I am doing it and then provide the full source afterwards.


	#$filepath = Join-Path -Path $Path -ChildPath "$computer.xml"
	if ($local)
	{
		$CCMEXEC = get-process -ComputerName $computer -name CcmExec
	}
	else
	{
		$CCMEXEC = Invoke-Command -ComputerName $computer { get-process -name CcmExec }
	}
	if ($local)
	{
		$SCOM = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | where { $_.displayname -like "*operations manager agent*" } | select displayname
		
	}
	else
	{
		$SCOM = invoke-command -computer $computer { Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* } | where displayname -like "*operations manager agent*" | select displayname
	}
	
	if ($local)
	{
		#$ENDPOINT = Get-RemoteSoftware -ComputerName $computer | where name -like "*Symantec endpoint*" | select name
		$ENDPOINT = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | where { $_.displayname -like "*Symantec endpoint*" } | select displayname
	}
	if ($dcom)
	{
		$TimeService = Get-WmiObject -ComputerName $computer -classname win32_Service | where { $_.name -eq "W32time" } | select -ExpandProperty state
	}
	Else
	{
		$TimeService = Get-CimInstance -ComputerName $computer -classname win32_Service | where { $_.name -eq "W32time" } | select -ExpandProperty state
	

Thanks to Irwin, I used the variables to store the end result of values that I want to look up. I create a foreach loop and include the variables within the loop. In my original script at the end of the loop I then export that to a XML file. I am planning to change that so that it outputs that so I can pipe that to other cmdlets….and this way I could create a function out of it…and create a module.

The full code is below. Next time I will write up on how I pass this to PScribo for reporting.