The firm I work at does not give users local administrator access for several reasons. We did an audit of our systems and found out several users had local administrator privileges that should not have. In order to keep track of all systems all of the time, I wrote the following two PowerShell scripts to report systems in which a user is part of the administrators group.
LocalAdministrators.ps1
This is a two step process, using SCCM Application deployment. The first step is to use a custom detection method written in PowerShell. The detection script queries the local administrator group of the system it is being executed on. It excludes members in the $MemberExclusions and systems in the $SystemExclusions arrays. I hard coded the exclusions in the detection script so that I can go right in there and directly add users and systems as needed. When you add a system to the application detection method, you also need to add the system to the exclusions.txt file. If there are no users in the administrators group, then the application detection script will return an "installed" status back to SCCM. If there are additional users in the group, besides the excluded, then the script will return a "not installed" message back to SCCM.
The only portion of the LocalAdministratorsDetection.ps1 file you need to modify are lines 19, 26, and 27.
The only portion of the LocalAdministratorsDetection.ps1 file you need to modify are lines 19, 26, and 27.
When a "not installed" message is returned back, which is an exit code 0, SCCM will now execute the LocalAdministrators.ps1 script to "install" the application. I wanted to have emails generated when this script executes, so I had to find a way to execute the script with a domain account, instead of the normal system account. This was achieved by placing a copy of psexec.exe in the same folder as the localadministrators.ps1 file exists. Now the way to set this up is to create a normal application deployment in SCCM 2012. As you setup the deployment types, under the Programs tab, you will need to use the following command line:
psexec.exe \\%COMPUTERNAME% -u <domain>\<domain account> -p <password> -h cmd.exe /c "echo . | powershell.exe -executionpolicy bypass -file \\<Directory>\LocalAdministrators.ps1"
The only parts of the psexec.exe command line you need to customize for your environment will be those highlighted in bold. This command line executes the powershell script using the specified domain account. The %COMPUTERNAME% grabs the computer name of the system it is being executed on.
The LocalAdministrators.ps1 script will now get a list of all users in the administrators group that are not excluded in the exclusions.txt file, which also exists in the same directory as the .ps1 file. You will need to create a file called EmailAddresses.txt, which will have a list of email addresses that you want to be emailed a report. You also need to create an exclusions.txt file. This will have a list of systems to exclude from the query. The only parts of the localadministrators.ps1 file you need to customize are Lines 27, 28, 77, and 83. At the end of the script, it will send out an email to all addresses in the EmailAddresses.txt file. Finally, it renames the file LocalAdministrators.log to LocalAdministrators_Emailed.log. When the application detection is rerun, it will see the _Emailed in the filename and return a success if there are extra users in the local administrator group. If there are no extra users in the group and that file exists, then the application detection method will delete the .log file.
You can download the LocalAdministrators.ps1 script from here.
You can download the LocalAdministratorsDetection.ps1 script from here.
LocalAdministrators.ps1
1: <#
2: .NOTES
3: ===========================================================================
4: Created with: SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.98
5: Created on: 11/23/2015 1:14 PM
6: Created by: Mick Pletcher
7: Organization:
8: Filename: LocalAdministrators.ps1
9: ===========================================================================
10: .DESCRIPTION
11: This script will open query the local administrators group. It generates
12: a log file if there are users in the local administrators group that are
13: not in the exclusions group. A .log file is written to the local HDD. The
14: script then returns a error code 0 back to SCCM, which will initiate a
15: software deployment. At that point, the secondary script will email
16: the .log file to the appropriate users. That script then deletes the
17: .log file which will then create a successful
18: #>
19:
20: #Declare Global Variables
21: Set-Variable -Name Body -Force
22: Set-Variable -Name EmailAddress -Force
23: Set-Variable -Name EmailAddresses -Force
24: Set-Variable -Name Exclusions -Force
25: Set-Variable -Name LocalAdmin -Force
26: Set-Variable -Name LocalAdmins -Force
27: Set-Variable -Name LogFile -Value $env:windir"\Logs\LocalAdministrators.log" -Force
28: Set-Variable -Name LogFileEmailed -Value $env:windir"\Logs\LocalAdministrators_Emailed.log" -Force
29: Set-Variable -Name Member -Force
30: Set-Variable -Name Members -Force
31: Set-Variable -Name Output -Force
32: Set-Variable -Name Prof -Force
33: Set-Variable -Name Profiles -Force
34: Set-Variable -Name RelativePath -Force
35:
36: cls
37: $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"
38: $Body = "Local Administrator(s)" + [char]13 + "---------------------------" + [char]13
39: $EmailAddresses = @()
40: $EmailAddresses = Get-Content -Path $RelativePath"EmailAddresses.txt"
41: $LocalAdmins = @()
42: $Members = net localgroup administrators | where { $_ -AND $_ -notmatch "command completed successfully" } | select -skip 4
43: $Profiles = Get-ChildItem -Path $env:SystemDrive"\users" -Force
44: $Exclusions = Get-Content -Path $RelativePath"Exclusions.txt"
45: Foreach ($Member in $Members) {
46: $Member = $Member.Split("\")
47: If ($Member.Count -gt 1) {
48: [string]$Member = $Member[1]
49: If ($Member -notin $Exclusions) {
50: Foreach ($Prof in $Profiles) {
51: If ($Member -eq $Prof) {
52: $LocalAdmins += $Member
53: }
54: }
55: }
56: }
57: Remove-Variable -Name Member
58: }
59: if ((Test-Path $LogFileEmailed) -eq $true) {
60: Remove-Item -Path $LogFileEmailed -Force
61: }
62: if ((Test-Path $LogFile) -eq $true) {
63: Remove-Item -Path $LogFile -Force
64: }
65: if ($LocalAdmins.Count -gt 0) {
66: if ((Test-Path $LogFile) -eq $false) {
67: New-Item -Path $LogFile -ItemType file -Force
68: }
69: foreach ($LocalAdmin in $LocalAdmins) {
70: Add-Content -Path $LogFile -Value $LocalAdmin -Force
71: $Body = $Body + $LocalAdmin + [char]13
72: }
73: }
74: If ($LocalAdmins.count -eq 1) {
75: $Output = $LocalAdmin + [char]32 + "is a local administrator on" + [char]32 + $env:COMPUTERNAME
76: foreach ($EmailAddress in $EmailAddresses) {
77: Send-MailMessage -To $EmailAddress -From "IT@acme.com" -Subject "Local Administrator Report" -Body $Output -SmtpServer "smtp.acme.com"
78: }
79: Rename-Item -Path $LogFile -NewName $LogFileEmailed -Force
80: } else {
81: $Output = "The attached file lists all local administrators on" + [char]32 + $env:COMPUTERNAME
82: foreach ($EmailAddress in $EmailAddresses) {
83: Send-MailMessage -To $EmailAddress -From "IT@acme.com" -Subject "Local Administrator Report" -Body $Output -Attachments $LogFile -SmtpServer "smtp.acme.com"
84: }
85: Rename-Item -Path $LogFile -NewName $LogFileEmailed -Force
86: }
87: $LocalAdmins = $null
88:
89: #Cleanup Global Variables
90: Remove-Variable -Name Body -Force
91: Remove-Variable -Name EmailAddress -Force
92: Remove-Variable -Name EmailAddresses -Force
93: Remove-Variable -Name Exclusions -Force
94: Remove-Variable -Name LocalAdmin -Force
95: Remove-Variable -Name LocalAdmins -Force
96: Remove-Variable -Name LogFile -Force
97: Remove-Variable -Name LogFileEmailed -Force
98: Remove-Variable -Name Members -Force
99: Remove-Variable -Name Output -Force
100: Remove-Variable -Name Prof -Force
101: Remove-Variable -Name Profiles -Force
102:
LocalAdministratorsDetection.ps1
1: <#
2: .NOTES
3: ===========================================================================
4: Created with: SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.98
5: Created on: 11/23/2015 1:14 PM
6: Created by: Mick Pletcher
7: Organization:
8: Filename: LocalAdministratorsDetectionMethod.ps1
9: ===========================================================================
10: .DESCRIPTION
11: This script will query the local administrators group. It will return a
12: success to SCCM if there are no members in the local administrators
13: group or if a system is in the SystemExclusions array or a user is
14: in the MemberExclusions variable.
15: #>
16:
17: #Declare Global Variables
18: Set-Variable -Name LocalAdmins -Force
19: Set-Variable -Name LogFile -Value $env:windir"\Logs\LocalAdministrators_Emailed.log" -Force
20: Set-Variable -Name Member -Force
21: Set-Variable -Name MemberExclusions -Force
22: Set-Variable -Name Members -Force
23: Set-Variable -Name SystemExclusions -Force
24:
25: cls
26: $MemberExclusions = @("Domain Admins","Workstation Admins")
27: $SystemExclusions = @("SYSTEM01")
28: $LocalAdmins = @()
29: $Members = net localgroup administrators | where { $_ -AND $_ -notmatch "command completed successfully" } | select -skip 4
30: $Profiles = Get-ChildItem -Path $env:SystemDrive"\users" -Force
31: Foreach ($Member in $Members) {
32: $Member = $Member.Split("\")
33: If ($Member.Count -gt 1) {
34: [string]$Member = $Member[1]
35: If ($Member -notin $MemberExclusions) {
36: $LocalAdmins += $Member
37: }
38: }
39: Remove-Variable -Name Member
40: }
41: if (($LocalAdmins.Count -eq 0) -and ((Test-Path -Path $LogFile) -eq $true)) {
42: Remove-Item -Path $LogFile -Force
43: }
44: if (($LocalAdmins.Count -gt 0) -and ($env:COMPUTERNAME -notin $SystemExclusions) -and ((Test-Path -Path $LogFile) -eq $false )) {
45: Start-Sleep -Seconds 5
46: exit 0
47: } else {
48: Write-Host "No Local Administrators"
49: Start-Sleep -Seconds 5
50: exit 0
51: }
52: $LocalAdmins = $null
53:
54: #Cleanup Global Variables
55: Remove-Variable -Name LocalAdmins -Force
56: Remove-Variable -Name LogFile -Force
57: Remove-Variable -Name Member -Force
58: Remove-Variable -Name MemberExclusions -Force
59: Remove-Variable -Name Members -Force
60: Remove-Variable -Name SystemExclusions -Force
61:
0 comments:
Post a Comment