I’ve recently been looking at extending the standard set of auditing (from the previous scripts mentioned in Part 1, Part 2, and Part 3) to include DHCP scope information, and IIS-based website information.
Before getting into DHCP and IIS, I run an audit of all services, like this:
1 2 3 4 5 6 7 8 9 10 11 |
# Get WMI data $getservices = gwmi win32_service -ea 0 | select name, caption, startname, startmode; $servicescount = ($getservices | measure-object).count; # Convert service info into an array if only 1 service is found if ($servicescount -eq 1) { $temparray = @(); $temparray += $getservices; $getservices = $temparray; } |
$getservices now contains all of your service information.
The next section gathers DHCP data, but checks the above variable, $getservices, for the DHCP Server service first.
I’ve used an “old-school” method to get the DHCP data, so that the script will work on all versions of PowerShell and Windows operating systems. There are some very good DHCP cmdlets in the later versions of PowerShell, but I can’t rely on all servers having the newest/compatible version.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# If the DHCP Server service is installed if ($getservices | where {$_.name -eq "dhcpserver"}) { # Retrieve DHCP dump of information, looking for the "add scope" line $alldhcp = netsh dhcp server dump | select-string -pattern "dhcp server" | select-string -pattern "add scope" # If DHCP scope data is found if ($alldhcp) { $getscopes = @(); foreach ($line in $alldhcp) { # Split line to remove junk and create individual data fields in array $scopetext = ($alldhcp -split "add scope")[1] $scopearray = $line -split ' +(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)' $templine = "" | select iprange, subnetmask, scopename, scopedescription; $templine.iprange = ($scopearray[5]).trim() $templine.subnetmask = ($scopearray[6]).trim() $templine.scopename = ($scopearray[7]).trim('"') $templine.scopedescription = ($scopearray[8]).trim('"') $getscopes = $getscopes + $templine } $scopecount = ($getscopes | measure-object).count; # Convert DHCP scope info into an array if only 1 scope is found if ($scopecount -eq 1) { $temparray = @(); $temparray += $getscopes; $getscopes = $temparray; } } } |
$getscopes should now look like this (assuming you have DHCP scopes configured):
For IIS websites, we first check the $features variable gathered from the previous script from Part 3, and then check for both IIS6 and II7+ version websites:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
$getiis = @() # Check is IIS feature is installed if (($features | where {$_.name -eq "IIS-WebServer"}) -ne $null) { # Check for IIS7+ based websites try { $sites = get-childItem -path IIS:\Sites; # If websites are found if ($sites) { # Loop thorugh each website found foreach ($site in $sites) { # Loop through and gather binding information foreach ($binding in ($site.bindings.collection | where {$_.protocol -like "http*"})) { $tempiis = "" | select websitename, apppool, enabledprotocols, bindinghostname, bindingport, bindingipaddress; $tempiis.websitename = $site.name $tempiis.apppool = $site.applicationpool $tempiis.enabledprotocols = $site.enabledprotocols $bindinginformation = $binding.bindinginformation.split(":"); $tempiis.bindinghostname = $bindinginformation[2] $tempiis.bindingport = $bindinginformation[1] $tempiis.bindingipaddress = $bindinginformation[0] $getiis = $getiis + $tempiis; } } } } catch {} # Check for IIS6 based websites try { $sites = gwmi -namespace "root/MicrosoftIISv2" -class 'IIsWebServerSetting'; # If websites are found if ($sites) { # Loop through each website found foreach ($site in $sites) { # Loop through and gather binding information foreach ($binding in $site.serverbindings) { $tempiis = "" | select websitename, apppool, enabledprotocols, bindinghostname, bindingport, bindingipaddress; $tempiis.websitename = $site.servercomment; $tempiis.apppool = $site.apppoolid; $tempiis.enabledprotocols = $site.enabledprotocols; $tempiis.bindinghostname = $binding.hostname $tempiis.bindingport = $binding.port $tempiis.bindingipaddress = $binding.ip $getiis = $getiis + $tempiis; } } } } catch {} } # Convert IIS into an array if only 1 scope is found $iiscount = ($getiis | measure-object).count; if ($iiscount -eq 1) { $temparray = @(); $temparray += $getiis; $getiis = $temparray; } |
Assuming you have IIS websites configured, $getiis should have one or more entries, like this:
Hi Kamal,
I follow regulary your post. Very interresting. But for this one, just a question : Why use netsh to query info about DCHP ? I know that Netsh is a swiss knife DOS cmd. but in 2020, using the cmdlets of DHCPServer PS module seems to be more appropriate.
regards
Olivier
Hi Olivier,
I tried to articulate it in the post, but maybe I was being too subtle?
In my experience (working across a lot of different companies) is that very few of them run the latest version of anything. Latest version (or even n-1 version) of Windows Server? Rare. Similarly, the PowerShell versions usually never get upgraded. Your experience might be different – but having the latest PS modules in place is an extremely rare sight for me, and upgrading PowerShell across hundreds or thousands of servers is also next to impossible to get any traction on.
As an example, one of my recent assignments had me reviewing 160+ DHCP servers in a single domain (most running Server 2008 R2, and PowerShell v3 – but also some Windows Server 2003 in the mix). Not a small number of PS upgrades required.
So, with that in mind, I (usually) am forced to write more “universal” and backwards-compatible PowerShell scripts that will work on any version of PowerShell and any version of Windows Server; in that way, I know they will always work and give me the results I need.
It’s pretty frustrating not having the latest and greatest, but sometimes you just need to work within the boundaries of what’s in front of you.
Excellent post Kamal, thanks for this.