cancel
Showing results for 
Search instead for 
Did you mean: 

Manage and Monitor PowerShell Scripts

Community Manager

Anyone who knows me knows that I’m a fan of PowerShell. “Fan” is a diminutive version of the word “fanatic,” and in this instance both are true. That’s why I was so excited to see that PowerShell script output is now supported in Server Configuration Monitor (SCM).

Since SCM’s release, I’ve always thought it was a great idea to monitor the directory where you store your scripts to make sure they didn’t vary and to validate changes over time, even going in and reverting them in case there was a change without approval. However, that part was available in the initial release of SCM. Using PowerShell with SCM, you can monitor your C:\Scripts\*.ps1 files and get notified when any deviate from their baselines.

Using PowerShell scripts to pull information from systems you’re monitoring is only limited by your scripting prowess. But let me say this plainly: You don’t need to be a scripting genius. The THWACK® members are here to be your resources. If you have something great you wrote, post about it. If you need help formatting output, post about it. If you can’t remember how to get a list of all the software installed on a system, post about it. Someone here has probably already done the work.

Monitoring the Server Roles

Windows now handles many of the “roles” of a machine (Web Server, Active Directory Server, etc.) based on the installed features. There never was a really nice way to understand what roles were installed on a machine outside the Server Manager. This is especially true if you’re running Windows Server Core because it has no Server Manager.

Now, you can just write yourself a small PowerShell script:

Get-WindowsFeature | Where-Object { $_.Installed } | Select-Object -Property Name, DisplayName | Sort-Object -Property Name

…and get the list of all features displayed for you.

Name                      DisplayName

----                      -----------

FileAndStorage-Services   File and Storage Services

File-Services             File and iSCSI Services

FS-Data-Deduplication     Data Deduplication

FS-FileServer             File Server

MSMQ                      Message Queuing

MSMQ-Server               Message Queuing Server

MSMQ-Services             Message Queuing Services

NET-Framework-45-ASPNET   ASP.NET 4.7

NET-Framework-45-Core     .NET Framework 4.7

NET-Framework-45-Features .NET Framework 4.7 Features

NET-WCF-Services45        WCF Services

NET-WCF-TCP-PortSharing45 TCP Port Sharing

PowerShell                Windows PowerShell 5.1

PowerShell-ISE            Windows PowerShell ISE

PowerShellRoot            Windows PowerShell

Storage-Services          Storage Services

System-DataArchiver       System Data Archiver

Web-App-Dev               Application Development

Web-Asp-Net45             ASP.NET 4.7

Web-Common-Http           Common HTTP Features

Web-Default-Doc           Default Document

Web-Dir-Browsing          Directory Browsing

Web-Dyn-Compression       Dynamic Content Compression

Web-Filtering             Request Filtering

Web-Health                Health and Diagnostics

Web-Http-Errors           HTTP Errors

Web-Http-Logging          HTTP Logging

Web-ISAPI-Ext             ISAPI Extensions

Web-ISAPI-Filter          ISAPI Filters

Web-Log-Libraries         Logging Tools

Web-Metabase              IIS 6 Metabase Compatibility

Web-Mgmt-Compat           IIS 6 Management Compatibility

Web-Mgmt-Console          IIS Management Console

Web-Mgmt-Tools            Management Tools

Web-Net-Ext45             .NET Extensibility 4.7

Web-Performance           Performance

Web-Request-Monitor       Request Monitor

Web-Security              Security

Web-Server                Web Server (IIS)

Web-Stat-Compression      Static Content Compression

Web-Static-Content        Static Content

Web-WebServer             Web Server

Web-Windows-Auth          Windows Authentication

Windows-Defender          Windows Defender Antivirus

WoW64-Support             WoW64 Support

XPS-Viewer                XPS Viewer

This is super simple. If someone adds or removes one of these features, you’ll know moments after it’s done because it would deviate from your baseline.

Monitoring Local Administrators

This got me thinking about all manner of other possible PowerShell script uses. One that came to mind immediately was local security. We all know the local administrator group is an easy way to have people circumvent security best practices, so knowing who is in that security group has proven difficult.

Now that we don’t have those limitations, let’s look at the local admins group and look at local users.

Get-LocalGroupMember -Group Administrators | Where-Object { $_.PrincipalSource -eq "Local" } | Sort-Object -Property Name

Now, you’ll get returned a list of all the local users in the Administrators group.

ObjectClass Name                         PrincipalSource
----------- ----                         ---------------
User        NOCKMSMPE01V\Administrator   Local
User        NOCKMSMPE01V\Automation-User Local

Now we’ll know if someone is added or deleted. You could extend this to know when someone is added to power users or any other group. If you really felt like going gang-busters, you could ask for all the groups, and then enumerate the members of each.

Local Certificates

These don’t have to be relegated to PowerShell one-liners either. You can have entire scripts that return a value that you can review.

Also, on the security front, it might be nice to know if random certificates start popping up everywhere. Doing this by hand would be excruciatingly slow. Thankfully it’s pretty easy in PowerShell.

$AllCertificates = Get-ChildItem -Path Cert:\LocalMachine\My -Recurse

# Create an empty list to keep the results

$CertificateList = @()

ForEach ( $Certificate in $AllCertificates )

{

    # Check to see if this is a "folder" or a "certificate"

    if ( -not ( $Certificate.PSIsContainer ) )

    {

        # Certificates are *not* containers (folders)

        # Get the important details and add it to the $CertificateList

        $CertificateList += $Certificate | Select-Object -Property FriendlyName, Issuer, Subject, Thumbprint, NotBefore, NotAfter

    }

}

$CertificateList

As you can see, you aren’t required to stick with one-liners. Write whatever you need for your input. As long as there’s output, SCM will capture it and present it in a usable format for parsing.

FriendlyName : SolarWinds-Orion
Issuer       : CN=SolarWinds-Orion
Subject      : CN=SolarWinds-Orion
Thumbprint   : AF2A630F2458E0A3BE8D3EF332621A9DDF817502
NotBefore    : 10/12/2018 5:59:14 PM
NotAfter     : 12/31/2039 11:59:59 PM

FriendlyName :
Issuer       : CN=SolarWinds IPAM Engine
Subject      : CN=SolarWinds IPAM Engine
Thumbprint   : 4527E03262B268D2FCFE4B7B4203EF620B41854F
NotBefore    : 11/5/2018 7:13:34 PM
NotAfter     : 12/31/2039 11:59:59 PM

FriendlyName :
Issuer       : CN=SolarWinds-Orion
Subject      : CN=SolarWinds Agent Provision - cc10929c-47e1-473a-9357-a54052537795
Thumbprint   : 2570C476DF0E8C851DCE9AFC2A37AC4BDDF3BAD6
NotBefore    : 10/11/2018 6:46:29 PM
NotAfter     : 10/12/2048 6:46:28 PM

FriendlyName : SolarWinds-SEUM_PlaybackAgent
Issuer       : CN=SolarWinds-SEUM_PlaybackAgent
Subject      : CN=SolarWinds-SEUM_PlaybackAgent
Thumbprint   : 0603E7052293B77B89A3D545B43FC03287F56889
NotBefore    : 11/4/2018 12:00:00 AM
NotAfter     : 11/5/2048 12:00:00 AM

FriendlyName : SolarWinds-SEUM-AgentProxy
Issuer       : CN=SolarWinds-SEUM-AgentProxy
Subject      : CN=SolarWinds-SEUM-AgentProxy
Thumbprint   : 0488D26FD9576293C30BB5507489D96C3ED829B4
NotBefore    : 11/4/2018 12:00:00 AM
NotAfter     : 11/5/2048 12:00:00 AM

FriendlyName : WildcardCert_Demo.Lab
Issuer       : CN=demo-EASTROOTCA-CA, DC=demo, DC=lab
Subject      : CN=*.demo.lab, OU=Information Technology, O=SolarWinds Demo Lab, L=Austin, S=TX, C=US
Thumbprint   : 039828B433E38117B85E3E9C1FBFD5C1A1189C91
NotBefore    : 3/30/2018 4:37:41 PM
NotAfter     : 3/30/2020 4:47:41 PM

Antivirus Exclusions

How about your antivirus exclusions? I’m sure you really, really want to know if those change.

$WindowsDefenderDetails = Get-MpPreference

$WindowsDefenderExclusions = $WindowsDefenderDetails.ExclusionPath

$WindowsDefenderExclusions | Sort-Object

Now you’ll know if something is added to or removed from the antivirus exclusion list.

C:\inetpub\SolarWinds
C:\Program Files (x86)\Common Files\SolarWinds
C:\Program Files (x86)\SolarWinds
C:\ProgramData\SolarWinds
C:\ProgramData\SolarWindsAgentInstall

Trying to find this out by hand would be tedious, so let’s just have SCM do the work for you.

This is all just a sample of the power of PowerShell and SCM. We’d love to know what you’ve got in mind for your environment. So, download a trial or upgrade to the latest version of SCM. Be sure to share your excellent scripting adventure so the rest of us can join in the fun!

22 Comments
ondrej.hajek
Level 8

These seem very useful, thanks

KMSigma Community Manager
Community Manager

Thanks very much!  One thing I should point out about my choices.

I'm big on using the Sort-Object PowerShell function because I don't want an alert when a "config" changes because:

Rhinoceros

Elephant

Pachyderm

is compared to

Elephant

Pachyderm

Rhinoceros

wluther
Level 16

Great stuff here, KMSigma​!

Between allowing data to be gathered via PowerShell and SWQL, SCM is quickly becoming super powerful.

SCM feels like it could eventually be the missing link, being able to check the data deep down into the cracks, where some of the other, bigger, tools slow down or can't get to.

KMSigma Community Manager
Community Manager

I agree 100%.  When it was originally just an idea I had a laundry list of needs/wants for the product.  I love what I've seen so far and the trajectory that the product and development teams are on.  I'm looking for better and better things over the next few releases.

cfizz34
Level 12

How would you build upon the local admin group changes so that it tracts when someone or a group is added to the local admins group?

KMSigma Community Manager
Community Manager

It should already do that if you add it to an SCM policy.  If you build a policy and add a PowerShell element with the above code it'll run it on a schedule.  If the output changes at any time you will be notified.  If you are part of an Active Directory domain (probably, but not always), you may want to just use:

Get-LocalGroupMember -Group Administrators | Sort-Object -Property Name

If you use this one it pulls in both local users and domain users who are members of the local administrators group.

cfizz34
Level 12

What about a script to show dhcp changes.

KMSigma Community Manager
Community Manager

I'm sure it's possible, but it depends on what you want to see?  New/removed reservations?  Changes to server/scope variables?  All are possible.

cfizz34
Level 12

I'd like to see if any scope options get added/changed and/or if a new scope is added/removed/changed/updated.

KMSigma Community Manager
Community Manager

This is what I came up with in my lab.  These are all for IPv4 addresses and not IPv6 addresses.

<# Scope Creation/Edits/Deletes: #>

Get-DhcpServerv4Scope | Sort-Object -Property ScopeID | Format-List -Property ScopeId, Name, SubnetMask, StartRange, EndRange, ActivatePolicies, Delay, Description, LeaseDuration, MaxBootpClients,  NapEnable, NapProfile, State, SuperscopeName, Type

<# Get the option for each scope: #>

$Scopes = Get-DhcpServerv4Scope

$ScopeOptions = @()

ForEach ( $Scope in $Scopes )

{

   # Write-Host "Processing Scope: $( $Scope.ScopeId ) [$( $Scope.Name )]"

   $Options = $Scope | Get-DhcpServerv4OptionValue | Sort-Object OptionId

   ForEach ( $Option in $Options )

   {

      # Write-Host "`tProcessing Scope: $( $Option.Name ) [$( $Option.value )]"

      $ScopeOptions += New-Object -TypeName PSObject -Property @{ "ScopeID"     = $Scope.ScopeID;

                                                                  "OptionID"    = $Option.OptionID;

                                                                  "OptionName"  = $Option.Name;

                                                                  "OptionType"  = $Option.Type;

                                                                  "OptionValue" = $Option.Value }

   }

}

$ScopeOptions | Select-Object -Property ScopeID, OptionID, OptionName, OptionType, OptionValue

<# DHCP Reservations: #>

Get-DhcpServerv4Scope | Sort-Object -Property ScopeId | Get-DhcpServerv4Reservation | Sort-Object -Property ClientId | Format-Table -AutoSize

Your results may vary.  I'm by no means a specialist when it comes to managing DHCP via PowerShell.  I read Deploy DHCP Using Windows PowerShell | Microsoft Docs  for most of my logic.

cfizz34
Level 12

You think we will ever get the ability to export/import scm profiles?

KMSigma Community Manager
Community Manager

It's in there as of version 1.2

pastedImage_0.png

cfizz34
Level 12

Good start, but I'm talking about being shareable like the SAM templates.

cfizz34
Level 12

awesome, and thanks!!! the top and bottom one worked, but the middle one does not give me any output.

<# Get the option for each scope: #>

$Scopes = Get-DhcpServerv4Scope

$ScopeOptions = @()

ForEach ( $Scope in $Scopes )

{

   # Write-Host "Processing Scope: $( $Scope.ScopeId ) [$( $Scope.Name )]"

   $Options = $Scope | Get-DhcpServerv4OptionValue | Sort-Object OptionId

   ForEach ( $Option in $Options )

   {

      # Write-Host "`tProcessing Scope: $( $Option.Name ) [$( $Option.value )]"

      $ScopeOptions += New-Object -TypeName PSObject -Property @{ "ScopeID"     = $Scope.ScopeID;

                                                                  "OptionID"    = $Option.OptionID;

                                                                  "OptionName"  = $Option.Name;

                                                                  "OptionType"  = $Option.Type;

                                                                  "OptionValue" = $Option.Value }

   }

}

$ScopeOptions | Select-Object -Property ScopeID, OptionID, OptionName, OptionType, OptionValue

KMSigma Community Manager
Community Manager

They are share-able in the Content Exchange portion of the SCM forum.  Just look for documents (appear as an "open" box).  You are correct that it hasn't been fully integrated to the product like SAM, but that sounds like an excellent feature request for SCM​ if it's not already in there.  If it is in there, then you should up-vote it.

KMSigma Community Manager
Community Manager

Might be a version thing.  I only have one version of Windows on which to test, so that's what I did.  If you run it locally on a DHCP server does it provide results?

cfizz34
Level 12

I'm on this version

PS C:\Windows\system32> $PSVersionTable.PSVersion

Major  Minor  Build  Revision

-----  -----  -----  --------

5      1      14393  2125

cfizz34
Level 12

At line:1 char:30

+ ForEach ( $Scope in $Scopes )

+                              ~

Missing statement body in foreach loop.

    + CategoryInfo          : ParserError: (Smiley Happy [], ParentContainsErrorRecordException

    + FullyQualifiedErrorId : MissingForeachStatement

KMSigma Community Manager
Community Manager

Ah - syntax.  If you are just copying and pasting into a PowerShell window, then we need to move the curly braces on the line after the "ForEach ( $this in $that )" to the end of that line instead of on the next line.

<# Get the option for each scope: #>

$Scopes = Get-DhcpServerv4Scope

$ScopeOptions = @()

ForEach ( $Scope in $Scopes ) {

   # Write-Host "Processing Scope: $( $Scope.ScopeId ) [$( $Scope.Name )]"

   $Options = $Scope | Get-DhcpServerv4OptionValue | Sort-Object OptionId

   ForEach ( $Option in $Options ) {

      # Write-Host "`tProcessing Scope: $( $Option.Name ) [$( $Option.value )]"

      $ScopeOptions += New-Object -TypeName PSObject -Property @{ "ScopeID"     = $Scope.ScopeID;

                                                                  "OptionID"    = $Option.OptionID;

                                                                  "OptionName"  = $Option.Name;

                                                                  "OptionType"  = $Option.Type;

                                                                  "OptionValue" = $Option.Value }

   }

}

$ScopeOptions | Select-Object -Property ScopeID, OptionID, OptionName, OptionType, OptionValue

cfizz34
Level 12

rock star, thanks!

i_like_eggs
Level 13

OH BOY, im really glad i downloaded this module, now to brush up on some 'PS' i love you

bobmarley
Level 15

Thanks much!

About the Author
Kevin's first computer was the family TI-99/4A. He's learned computing the best way possible: by fixing his own broken machines. He was a SolarWinds customer for nearly 10 years before joining the company. He's worked the range of IT jobs: from the 3-person consultancy to the international law firm. Along the way, he's become a SolarWinds advocate and evangelist of monitoring glory. His passions include shooting archery, blacksmithing, playing D&D, and helping IT professionals leave at a reasonable time each and every day.
Labels