This PowerShell script generates an html report listing all accounts used as logon account by services on servers in an Active Directory domain.
The script has filters to ignore accounts : NT Service, NT AUTHORITY and LocalSystem
https://github.com/sozezzo/Powershell/blob/master/Report/report-service-server.ps1
Apply filter by servers and services
1
2$FilterServerLike = "*" ## Select all servers
3$FilterServiceLike = "*" ## Select all services
Ignore accounts
1
2$IgnoreAccount_NT_Service = 1 ## NT Service
3$IgnoreAccount_NT_AUTHORITY = 1 ## NT AUTHORITY
4$IgnoreAccount_LocalSystem = 1 ## LocalSystem
Powershell script to find servers and services
1
2<#
3
4 report-service-server.ps1
5
6 Reads service configuration from all Windows servers in the current domain
7 and generates report listing all service logon account.
8
9 Version history:
10 08.08.2020 First release
11
12 #Reference : https://gallery.technet.microsoft.com/scriptcenter/PowerShell-script-to-find-6fc15ecb
13 * Use Job and missing nice features
14
15#>
16
17Clear
18
19## Begin Configuration ##
20
21$FilterServerLike = "*" ## Filter server
22$FilterServiceLike = "*" ## Filter service
23
24## Search for all server and all services ##
25#$FilterServerLike = "**" ## Search all server : "*"
26#$FilterServiceLike = "*" ## Search all service
27
28## Search for all server *sql* and all services mssql* ##
29#$FilterServerLike = "*sql*" ## Search all server with name *SQL*
30#$FilterServiceLike = "MSSQL*" ## Search service MSSQL*
31
32$IgnoreAccount_NT_Service = 1 ## NT Service
33$IgnoreAccount_NT_AUTHORITY = 1 ## NT AUTHORITY
34$IgnoreAccount_LocalSystem = 1 ## LocalSystem
35$ListServer = 1 ## Create table -- Server | #Services | Access status
36$reportFile = "$env:TEMP\report_service_server.html"
37## End Configuration ##
38
39## Global variables ##
40$ErrorActionPreference = "Stop"
41$currentDomain = $env:USERDOMAIN.ToUpper()
42$ServiceList = @{}
43$ServerList = @{}
44[string[]]$warnings = @()
45
46function get-server-info()
47{
48 param( $hostname )
49
50 if ( Test-Connection -ComputerName $hostname -Count 3 -Quiet ){
51 try {
52 # retrieve service list form a remove machine
53 $serviceList = @( gwmi -Class Win32_Service -ComputerName $hostname -Property Name,StartName,SystemName -ErrorAction Stop )
54 ##$serviceList
55
56 ##############################
57 # reads service list
58
59 if ( $serviceList.GetType() -eq [Object[]] ){
60 try
61 {
62 $serviceList = $serviceList | ? { $_.StartName.toUpper() }
63
64 if ($serviceList.Count -ge 1)
65 {
66 $arrID = $script:ServerList.Count+1
67 $ItemInfo = $hostname, $($serviceList.Count), ""
68 $script:ServerList.Add( $arrID, @( $ItemInfo ) )
69 } else
70 {
71 $arrID = $script:ServerList.Count+1
72 $ItemInfo = $hostname, "", "no services"
73 $script:ServerList.Add( $arrID, @( $ItemInfo ) )
74 }
75
76 #Apply Filter
77 if ($IgnoreAccount_NT_Service -eq 1) { $serviceList = $serviceList | Where-Object {$_.StartName -notlike "NT Service*" } | ? { $_.StartName } }
78 if ($IgnoreAccount_NT_AUTHORITY -eq 1) { $serviceList = $serviceList | Where-Object {$_.StartName -notlike "NT AUTHORITY*" } | ? { $_.StartName } }
79 if ($IgnoreAccount_LocalSystem -eq 1) { $serviceList = $serviceList | Where-Object {$_.StartName -notlike "LocalSystem" } | ? { $_.StartName } }
80
81 if ($FilterServiceLike -ne "*") { $serviceList = $serviceList | Where-Object {$_.Name -like $FilterServiceLike } }
82
83 foreach( $service in $serviceList ){
84
85 $arrID = $script:ServiceList.Count+1
86 $ItemInfo = $service.StartName, $($service.Name), $($service.SystemName)
87
88 $script:ServiceList.Add( $arrID, @( $ItemInfo ) )
89
90 }
91 }
92 catch {}
93 }
94 elseif ( $data.GetType() -eq [String] )
95 {
96 $script:warnings += "Fail to read service info"
97 }
98
99 }
100 catch
101 {
102 $global:warnings += @("$hostname | Failed to retrieve data $($_.toString())")
103 $arrID = $script:ServerList.Count+1
104 $ItemInfo = $hostname, "", "Failed"
105 $script:ServerList.Add( $arrID, @( $ItemInfo ) )
106 }
107 }
108 else
109 {
110 $global:warnings += @("$hostname | unreachable")
111 $arrID = $script:ServerList.Count+1
112 $ItemInfo = $hostname, "", "Unreachable"
113 $script:ServerList.Add( $arrID, @( $ItemInfo ) )
114 }
115}
116
117################# MAIN #################
118
119## Add-WindowsFeature RSAT-AD-PowerShell
120Import-Module ActiveDirectory
121
122# read computer accounts from current domain
123Write-Progress -Activity "Retrieving server list from ActiveDirectory" -Status "Processing..." -PercentComplete 0
124$serverServiceList = Get-ADComputer -Filter {OperatingSystem -like "Windows Server*"} -Properties DNSHostName, cn | Where-Object {$_.Name -like $FilterServerLike } | ? { $_.enabled }
125
126$count_servers = 0
127foreach( $server in $serverServiceList ){
128
129 $dnshostname = $server.dnshostname
130 $dnshostname
131
132 ++$count_servers
133 Write-Progress -Activity "Retrieving data from server $dnshostname ( $count_servers / $($serverServiceList.Count) ) " -Status "Processing..." -PercentComplete ( $count_servers * 100 / $serverServiceList.Count )
134
135 get-server-info $server.dnshostname
136
137}
138
139# prepare data table for report
140Write-Progress -Activity "Generating report" -Status "Please wait..." -PercentComplete 0
141
142$ServiceTable = @()
143foreach( $value in $serviceList.Values )
144{
145
146 $row = new-object psobject
147 Add-Member -InputObject $row -MemberType NoteProperty -Name "Account" -Value $(($value)[0])
148 Add-Member -InputObject $row -MemberType NoteProperty -Name "Service" -Value $(($value)[1])
149 Add-Member -InputObject $row -MemberType NoteProperty -Name "Server" -Value $(($value)[2])
150 $ServiceTable += $row
151}
152
153$ServerTable = @()
154foreach( $value in $ServerList.Values )
155{
156
157 $row = new-object psobject
158 Add-Member -InputObject $row -MemberType NoteProperty -Name "Server" -Value $(($value)[0])
159 Add-Member -InputObject $row -MemberType NoteProperty -Name "Services" -Value $(($value)[1])
160 Add-Member -InputObject $row -MemberType NoteProperty -Name "Status" -Value $(($value)[2])
161 $ServerTable += $row
162}
163
164#################
165# create report
166$datenow = Get-Date -format "yyyy-MMM-dd HH:mm"
167$report = "
168<!DOCTYPE html>
169<html>
170<head>
171<style>
172TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;white-space:nowrap;}
173TH{border-width: 1px;padding: 4px;border-style: solid;border-color: black}
174TD{border-width: 1px;padding: 2px 10px;border-style: solid;border-color: black}
175</style>
176</head>
177<body>
178<H1>Service & Server report for $currentDomain domain</H1>
179<H3>Server Filter : $FilterServerLike</br>
180Service Filter : $FilterServiceLike</br>
181Login : $env:UserDomain$env:UserName</br>
182Date : $datenow
183</H3>
184
185<H2>Discovered service accounts</H2>
186$( $ServiceTable | Sort Account | ConvertTo-Html Account, Service, Server -Fragment )
187Discovered $($ServiceTable.count) services.
188</br>
189
190<H2>Discovered servers</H2>
191$( $ServerTable | Sort Status, Server | ConvertTo-Html Server, Services, Status -Fragment )
192$($serverList.count) servers processed.
193</br>
194
195<H2>Warning messages</H2>
196$( $warnings | % { "<p>$_</p>" } )
197
198</body>
199</html>"
200
201Write-Progress -Activity "Generating report" -Status "Please wait..." -Completed
202$report | Set-Content $reportFile -Force
203Invoke-Expression $reportFile
Sources :
https://gallery.technet.microsoft.com/scriptcenter/PowerShell-script-to-find-6fc15ecb
Comments