$ServerName = Read-Host 'What is the FQDN of the Server to query?'
$RunningServices = Get-Service -computername $ServerName | Where-Object {$_.status -eq "running"} | Select-Object Status, Name, DisplayName
# ForEach ($RunningService in $RunningServices) {
# Get-Service -ComputerName $ServerName -Name $RunningService | Select-Object Status, Name, DisplayName
# Add-Content -Path $OutputFile -Value $RunningService
# }
Add-Content -Path $OutputFile -Value $RunningServices -Encoding ascii
As it stands, the script outputs the remote server’s ($ServerName) running processes to a text file ($OutputFile) as
@{Status=Running; Name=COMSysApp; DisplayName=COM+ System Application}
@{Status=Running; Name=CryptSvc; DisplayName=Cryptographic Services}
@{Status=Running; Name=DcomLaunch; DisplayName=DCOM Server Process Launcher}
@{Status=Running; Name=Dhcp; DisplayName=DHCP Client}
@{Status=Running; Name=Dnscache; DisplayName=DNS Client}
How would I remove the @{} stuff to have just the basic info put into the text file?
Example:
Status Name DisplayName
------ ---- ----------
running COMSysA.. COM+ System...
My commented code (the commented out “ForEach” loop) is my current thought process on how to achieve it, but not 100% if that is the direction. Any info/direction would be appreciated.
While the Export-CSV works, it overwrites the content of $OutputFile with the $RunningServices array. Then the $OutputFile contains all subsequent info after this piece of code.
While I can shuffle code pieces around, I need to have at least the top 2 lines of $OutputFile consisting of the $ServerName and the current Date/Time value.
There is no code indicating you are putting the computer and date in the $OutputFile. It sounds like you are wanting to a report more than just dump services information into a file. I recommend you go to the eBooks link above and look at “Creating HTML Reports in PowerShell” if you want to format a text file that way. You can just do it in a text file, but you are going to have much more flexibility using HTML versus plain text.
I would agree that HTML is more flexible and I do apologize for missing that piece when I initially posted. I took a bit of time and redid my script using HTML as the Output file. This is what I ultimately ended up with though I’m still “tinkering” with it. I’m not overly convinced that the “invoke-command” statements to get the local group memberships are the best and the Windows Update list isn’t/doesn’t appear happy for me. The first 2 octets of IP address information if it exists (NTP, IP Address, Default Gateway, DNS Server) is intentionally scripted to be redacted on the generated reports.
##############################
#
# Variables
#
##############################
$HKLM = 2147483650
$ServerName = Read-Host 'What is the FQDN of the Server to query?'
$LogFile = "$ServerName.html"
$LocalDir = Convert-Path .
$NewDir = "$LocalDir\Output"
#Test if Output path exists
$PathExists = Test-Path -PathType Container $NewDir
If ($PathExists) {
}
Else {
New-Item -ItemType Directory -Force -Path $NewDir | Out-Null
}
$OutputFile = $NewDir, $LogFile -Join, "\"
$Today = Get-Date
$Redactor = "***"
$Separator = "."
##############################
#
# Get Server Operating System
#
##############################
$OS = (Get-WMIObject Win32_OperatingSystem -computername $ServerName).caption
##############################
#
# List Running Services
#
##############################
$ServicesReport = @()
#$Services = Get-WMIObject -Class Win32_Service -ComputerName $ServerName | Where-Object {$_.Status -eq "running"}
$Services = Get-Service -computername $ServerName | Where-Object {$_.status -eq "running"} | Select-Object Status, Name, DisplayName
ForEach ($Service in $Services) {
$ServiceRow = New-Object -Type PSObject -Property @{
Status = $Service.Status
Name = $Service.Name
DisplayName = $Service.DisplayName
}
$ServicesReport += $ServiceRow
}
$ServicesReport = $ServicesReport | ConvertTo-Html -Fragment
##############################
#
# Installed Updates
#
##############################
$UpdatesReport = @()
$Updates = Get-WmiObject -ComputerName $ServerName -Class "win32_quickfixengineering" | Select PSComputerName, HotFixID, @{n="InstalledOn";e={[datetime]$_.psbase.properties["InstalledOn"].Value}},Description -ExcludeProperty InstalledOn | Sort-Object InstalledOn -descending
ForEach ($Update in $Updates) {
$UpdateRow = New-Object -Type PSObject -Property @{
InstalledOn = $Update.InstalledOn
HotFixID = $Update.HotFixID
Description = $Update.Description
}
$UpdatesReport += $UpdateRow
}
$UpdatesReport = $UpdatesReport | ConvertTo-HTML -Fragment
##############################
#
# List NTP Configuration
#
##############################
$reg = [wmiclass]"\\$ServerName\root\default:StdRegprov"
$key = "SYSTEM\CurrentControlSet\Services\W32Time\Parameters"
$regkey = "NtpServer"
$server = $reg.GetStringValue($HKLM, $key, $regkey)
$ServerVar = $server.sValue -split ","
$TimeServer = $ServerVar[0]
$TimeServerInfo = $TimeServer.split($Separator)
If ($TimeServerInfo[3] -eq $NULL) {
$TimeServerRedacted = $TimeServer
}
Else {
$TimeServerRedacted = $Redactor + "." + $Redactor + "." + $TimeServerInfo[2] + "." + $TimeServerInfo[3] #[0] = 1st Octet, [1] = 2nd Octet, [2] = 3rd Octet, [3] = 4th Octet
}
$typevalue = "Type"
$type = $reg.GetStringValue($HKLM, $key, $typevalue)
$Method = $Type.sValue
$NTPConfig = "$TimeServerRedacted - $Method"
##############################
#
# Installed Software
#
##############################
$Software = "Software section intentionally not ran. See KB974524 (https://support.microsoft.com/en-us/kb/974524) for further information."
##############################
#
# Network Configuration
#
##############################
$Networks = Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ServerName -EA Stop | ? {$_.IPEnabled}
ForEach ($Network in $Networks) {
$IPAddress = $Network.IpAddress[0]
$Address = $IPAddress.split($Separator)
$IPRedacted = $Redactor + "." + $Redactor + "." + $Address[2] + "." + $Address[3] #[0] = 1st Octet, [1] = 2nd Octet, [2] = 3rd Octet, [3] = 4th Octet
$SubnetMask = $Network.IPSubnet[0]
$DefaultGateway = $Network.DefaultIPGateway
$Gateway = $DefaultGateway.split($Separator)
$GatewayRedacted = $Redactor + "." + $Redactor + "." + $Gateway[2] + "." + $Gateway[3] #[0] = 1st Octet, [1] = 2nd Octet, [2] = 3rd Octet, [3] = 4th Octet
$DNSServers = $Network.DNSServerSearchOrder
$DNSByte = $DNSServers.split($Separator)
$DNSServerRedacted = $Redactor + "." + $Redactor + "." + $DNSByte[2] + "." + $DNSByte[3] #[0] = 1st Octet, [1] = 2nd Octet, [2] = 3rd Octet, [3] = 4th Octet
$IsDHCPEnabled = $false
If($network.DHCPEnabled) {
$IsDHCPEnabled = $true
}
$MACAddress = $Network.MACAddress
$DNSHostname = $Network.DNSHostName
$Description = $Network.Description
}
##############################
#
# Server Type
#
##############################
$CompConfig = Get-WMIObject -computer $ServerName -Class Win32_ComputerSystem
ForEach ($ObjItem in $CompConfig) {
$x = $ObjItem.PCSystemType
$Type = Switch ($x) {
1 {"Desktop"}
2 {"Mobile / Laptop"}
3 {"Workstation"}
4 {"Enterprise Server"}
5 {"Small Office and Home Office (SOHO) Server"}
6 {"Appliance PC"}
7 {"Performance Server"}
8 {"Maximum"}
default {"Unspecified Product Type"}
}
$y = $ObjItem.DomainRole
$Role = Switch ($y) {
0 {"Standalone Workstation"}
1 {"Member Workstation"}
2 {"Standalone Server"}
3 {"Domain Member Server"}
4 {"Backup Domain Controller"}
5 {"Primary Domain Controller"}
default {"Unspecified Domain Role"}
}
}
$ServerTypeRole = "$ServerName is a $Type and $Role"
##############################
#
# Admin & Guest Accounts
#
##############################
#// Admin Account
$adminAccount = Get-WmiObject Win32_UserAccount -computername $ServerName -filter "SID like 'S-1-5-%-500'" | Select-Object Domain,Name,Disabled
$adminName = Get-WmiObject Win32_UserAccount -computername $ServerName -filter "SID like 'S-1-5-%-500'" | Select-Object -expand Name
$adminUser = [ADSI] "WinNT://$ServerName/$adminName"
$adminUserPWD = [int]($adminUser.PasswordAge[0]/86400)
If ($adminAccount.Disabled -eq $FALSE) {
$adminStatus = "ENABLED"
}
Else {
$adminStatus = "DISABLED"
}
#//Guest Account
$GuestAccount = Get-WmiObject Win32_UserAccount -computername $ServerName -filter "SID like 'S-1-5-%-501'" | Select-Object Domain,Name,Disabled
$GuestName = Get-WmiObject Win32_UserAccount -computername $ServerName -filter "SID like 'S-1-5-%-501'" | Select-Object -expand Name
If ($GuestAccount.Disabled -eq $FALSE) {
$GuestStatus = "ENABLED"
}
Else {
$GuestStatus = "DISABLED"
}
##############################
#
# Admin & RDP Groups
#
##############################
$AdminMembers = Invoke-Command {net localgroup "Administrators" | Where {$_ -AND $_ -NotMatch "command completed successfully"} | Select -skip 4} -computer $ServerName
$RDPUsers = Invoke-Command {net localgroup "Remote Desktop Users" | Where {$_ -AND $_ -NotMatch "command completed successfully"} | Select -skip 4} -computer $ServerName
If ($RDPUsers -eq $NULL) {
$RDPUsers = "No accounts detected in Remote Desktop Users group"
}
##############################
#
# Create Audit Report
#
##############################
$HTMLHeader = @"
System Audit Report for $ServerName
"@
$HTMLMiddle = @"
$ServerName Audit Report
System Info
System Name
$ServerName
Sample Date/Time
$Today
OS
$OS
NTP Configuration
$NTPConfig
Installed Software
$Software
Network Configuration
DNS Hostname: $DNSHostname
Network Adapter: $Description
IP Address: $IPRedacted
Subnet Mask: $SubnetMask
Default Gateway: $GatewayRedacted
DNS Servers: $DNSServerRedacted
DHCP Enabled? $IsDHCPEnabled
MAC Address: $MACAddress
Server Type & Role
$ServerTypeRole
Admin Account Information
Name: $adminName
Status: $adminStatus
Password Age: $adminUserPWD days
Guest Account Information
Name: $GuestName
Status: $GuestStatus
Local Admin Group Members
$Admins
Remote Desktop Group Members
$RDPUsers
System Services - Running
The following services were detected to be running at the sample time above on $ServerName.
$ServicesReport
Installed Windows Update Information
The following Updates have been applied to $ServerName
$UpdatesReport
"@
#// Assemble the closing HTML for our report.
$HTMLEnd = @"
"@
#// Assemble the final report from all our HTML sections
$HTMLReport = $HTMLHeader + $HTMLMiddle + $HTMLEnd
#// Save the report out to a file in the current path
$HTMLReport | Out-File $OutputFile