Windows Server 2012 Automation with PowerShell Cookbook
上QQ阅读APP看书,第一时间看更新

Creating and e-mailing a superuser report

One of the questions I receive every time there is a security audit or review is How many super users are there? To find this out, I have to manually open up Active Directory and look at the membership of Domain Admins and Enterprise Admins groups. Once I have identified the users, the security team then wants a documented list of who has superuser rights, when they got them, and why.

If your environment is anything like mine, looking at the Domain Admin group membership will be very surprising. Even though we work hard to limit who has access, more and more users creep into these groups throughout the year. By the time they are identified, finding out when, why, and how they were added can be exceedingly difficult. What is needed is a method of keeping up on the changes as they happen.

In this recipe we will create a superuser report that reports on membership of these critical groups. This report will show which accounts are in each group, and even highlight any changes that occurred since the last run. Additionally, the report will be e-mailed for easy access and retention.

Getting ready

To perform this recipe you will need to be in an Active Directory domain, with a service account that has access to query AD groups. The script runs on a system as a scheduled job and saves files to a local directory.

How to do it...

To create the superuser report, we create the following PowerShell script:

[Object[]]$oSuperUsers = New-Object PSObject

# Query the super-user groups for members
$oSuperUsers += Get-ADGroupMember -Identity 'Domain Admins' `
-Recursive | Select-Object @{Name='Group';expression={'Domain Admins'}}, `
Name, objectClass
$oSuperUsers += Get-ADGroupMember -Identity 'Enterprise Admins' `
-Recursive | Select-Object @{Name='Group';expression={'Enterprise Admins'}}, `
Name, objectClass

# Report on current membership
$strMessage = $oSuperUsers | Format-Table Name, objectClass `
-GroupBy Group | Out-String 

$exportFile = "c:\temp\superusers.clixml"
if(Test-Path $exportFile)
{
    # Import the results from the last time the script was executed
    $oldUsers = Import-Clixml $exportFile

    # Identify and report on the changes
    $strMessage += "Changes`n"
    $strMessage += Compare-Object -ReferenceObject $oldUsers `
    -DifferenceObject $oSuperUsers | Select-Object @{Name="Group";`
    expression={$_.InputObject.Group}}, @{Name="Name";expression=`
    {$_.InputObject.Name}}, @{Name="Side";expression={$_.SideIndicator}}`
    | Out-String
}

# Export results from this execution
Export-Clixml -InputObject $oSuperUsers -Path $exportFile

# Email report to the administrator
Send-MailMessage -From reports@corp.contoso.com -Subject `
"Weekly SuperUser Report" -To admin@contoso.com -Body $strMessage `
-SmtpServer mail.contoso.com

How it works...

The first thing the script does is create a custom PowerShell object named $oSuperUsers to hold the group, name, and class information. A custom object is used here to make the results easier to manage and flexible further down the script. Get-ADGroupMember is then called against the Domain Admins and Enterprise Admins groups and populate the custom object. The membership of these two groups are organized by the group name and stored in the $strMessage variable.

An external file, c:\temp\superusers.clixml, is checked to see if this script has been executed before. If the file exists, it is loaded into the $oldUsers variable using Import-Clixml. This file holds an exported version of the $oSuperUsers object from the last run of the script. The two objects are compared using the Compare-Object command to highlight any differences and appended to $strMessage. Lastly, the current $oSuperUsers object is exported and overwrites the external file.

Finally, Send-MailMessage combines the group membership and changes into a simple text e-mail message. The message is sent via SMTP to a mail server and it will appear in the administrator's mailbox.

There's more...

To make full use of this script, it would be best to schedule it to run every week. To schedule the task, we save the command as a .PS1 file and use the following script to add the script into Windows Task Scheduler:

# Define the action to be executed
$taskAction = New-ScheduledTaskAction -Execute `
"%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe" `
-Argument "C:\scripts\superUser.ps1"

# Define the execution schedule
$taskTrigger = New-ScheduledTaskTrigger -Weekly -WeeksInterval 1 -At 5am `
-DaysOfWeek Sunday

# Define the user account to execute the script
$taskUser = "Corp\ScriptAdmin"
$taskPassword = 'P@$$w0rd'

# Name the task and register
$taskName = "Super User Report"
Register-ScheduledTask -TaskName $taskName -Action $taskAction `
-Trigger $taskTrigger -User $taskUser -Password $taskPassword

The script starts by creating New-ScheduledTaskAction. This command identifies the command to execute, in this case PowerShell.exe, and any additional arguments, such as our superUser.ps1 file. The -Argument option can be updated based on the location of your scripts.

Next, we define the schedule for the task. We do this by creating New-ScheduledTaskTrigger and define a start time and recurrence cycle. In this case we are executing our script at 5 a.m. every Sunday.

Next, we define our username and password to execute the script. In this situation we are using a predefined service account and storing the password in plain text.

Lastly, we use Register-ScheduledTask to save the task. Once completed, the task will appear in Windows Task Scheduler as shown in the following screenshot:

There's more...