最終,我正在嘗試創建一個腳本,該腳本將從遠程計算機串列中獲取作為域服務帳戶運行的所有 Windows 服務,并輸出一個包含三列的 csv 檔案:服務帳戶名稱、Windows 服務和主機名。我不知道如何用兩個陣列創建哈希表。我使用 = 僅使用一個鍵和一個陣列就取得了一些成功,但即使這樣也有一些問題,而且我正在閱讀這是低效的。
這是修改后的代碼,它使所有 Win 服務在我的本地系統上作為系統運行:
$server = $env:COMPUTERNAME
$tgtAcct = 'SYSTEM'
$reportCsv = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ("report.$(Get-Date -Format `"yyyMMdd_hhmmss`").csv")
$GetServiceAccounts = {
[CmdletBinding()]
param(
$hostname
)
$serviceList = @( Get-WmiObject -Class Win32_Service -ComputerName $hostname -Property Name, StartName, SystemName -ErrorAction Stop )
$serviceList
}
Function Process-CompletedJobs(){
$jobs = Get-Job -State Completed
ForEach ($job in $jobs) {
$data = Receive-Job $job
Remove-Job $job
If ($data.GetType() -eq [System.Object[]]) {
$serviceList = $data | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct) }
ForEach ($service in $serviceList) {
$account = $service.StartName
$winService = $service.Name
$occurance = $service.SystemName
}
}
}
}
Start-Job -ScriptBlock $GetServiceAccounts -Name "read_$($server)" -ArgumentList $server | Wait-Job > $null
Process-CompletedJobs
這是我嘗試過但不起作用的方法:
$server = $env:COMPUTERNAME
$tgtAcct = 'SYSTEM'
$serviceAccounts = @{}
$accountTable = @()
$winSvcTable = @()
$occurTable = @()
$reportCsv = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ("report.$(Get-Date -Format `"yyyMMdd_hhmmss`").csv")
$GetServiceAccounts = {
[CmdletBinding()]
param(
$hostname
)
$serviceList = @( Get-WmiObject -Class Win32_Service -ComputerName $hostname -Property Name, StartName, SystemName -ErrorAction Stop )
$serviceList
}
Function Process-CompletedJobs(){
$jobs = Get-Job -State Completed
ForEach ($job in $jobs) {
$data = Receive-Job $job
Remove-Job $job
If ($data.GetType() -eq [System.Object[]]) {
$serviceList = $data | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct) }
ForEach ($service in $serviceList) {
$account = $service.StartName
$winService = $service.Name
$occurance = $service.SystemName
$script:serviceAccounts.Item($account) = $winService
$script:serviceAccounts.Item($account) = $occurance
}
}
}
}
Start-Job -ScriptBlock $GetServiceAccounts -Name "read_$($server)" -ArgumentList $server | Wait-Job > $null
Process-CompletedJobs
ForEach ($serviceAccount in $serviceAccounts.Keys) {
ForEach ($occurance in $serviceAccounts.Item($serviceAccount)) {
ForEach ($winService in $serviceAccounts.Item($serviceAccount)) {
$row = New-Object PSObject
Add-Member -InputObject $row -MemberType NoteProperty -Name "Account" -Value $serviceAccount
Add-Member -InputObject $row -MemberType NoteProperty -Name "Service" -Value $winService
Add-Member -InputObject $row -MemberType NoteProperty -Name "Hostname" -Value $occurance
$accountTable = $row
}
}
}
$accountTable | Export-Csv $reportCsv
I'm trying to modify code written by Andrea Fortuna that almost does what I want but want to split the second column into two. Again, I'm also looking for how to do this without adding to each array using = if possible. https://www.andreafortuna.org/2020/03/25/windows-service-accounts-enumeration-using-powershell/
uj5u.com熱心網友回復:
如果您的目標是匯出到 CSV,那么單個頂級哈希表不是您想要的資料結構。
Export-Csv指望一個集合的單個物件,所以,這就是你要創建:
Function Process-CompletedJobs(){
$jobs = Get-Job -State Completed
ForEach ($job in $jobs) {
$data = Receive-Job $job
Remove-Job $job
If ($data.GetType() -eq [System.Object[]]) {
$serviceList = $data | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct) }
ForEach ($service in $serviceList) {
# don't assign this new object to anything - let it "bubble up" as output instead
[pscustomobject]@{
Account = $service.StartName
Service = $service.Name
Occurrence = $service.SystemName
}
}
}
}
}
現在你可以這樣做:
Start-Job -ScriptBlock $GetServiceAccounts -Name "read_$($server)" -ArgumentList $server | Wait-Job > $null
Process-CompletedJobs |Export-Csv ...
uj5u.com熱心網友回復:
那這個呢?
$server = $env:COMPUTERNAME
$tgtAcct = 'SYSTEM'
$reportCsv = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ("report.$(Get-Date -Format `"yyyMMdd_hhmmss`").csv")
$GetServiceAccounts = {
[CmdletBinding()]
param(
$hostname
)
$serviceList = @( Get-WmiObject -Class Win32_Service -ComputerName $hostname -Property Name, StartName, SystemName -ErrorAction Stop )
$serviceList
}
Function Process-CompletedJobs(){
$jobs = Get-Job -State Completed
$hashtable = @{}
ForEach ($job in $jobs) {
$data = Receive-Job $job
Remove-Job $job
If ($data.GetType() -eq [System.Object[]]) {
$serviceList = $data | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct) }
ForEach ($service in $serviceList) {
$account = $service.StartName
$winService = $service.Name
$occurance = $service.SystemName
$hashtable[$account] = @{winService = $winService; occurance = $occurance}
}
}
}
return $hashtable
}
Start-Job -ScriptBlock $GetServiceAccounts -Name "read_$($server)" -ArgumentList $server | Wait-Job > $null
$myHashTable = Process-CompletedJobs
uj5u.com熱心網友回復:
讓它變得簡單,它會起作用,這是完整的腳本,我已經嘗試過并且對許多服務器有效,您可以$hostnames = $env:COMPUTERNAME,host2,host3,..根據需要更改變數,并且我添加了一些引數以獲得結果的網格視圖來測驗并添加 force 和 notypeinfo。在匯出-csv
這是代碼,如果有幫助,我希望您將其標記為答案
$hostnames = $env:COMPUTERNAME
$tgtAcct = 'SYSTEM'
$reportCsv = Join-Path -Path ([Environment]::GetFolderPath("Desktop")) -ChildPath ("report.$(Get-Date -Format `"yyyMMdd_hhmmss`").csv")
$TableName = "System Accounts"
#Create a table
$Table = new-object System.Data.DataTable "$TableName"
#Create a coloumn and you can increase it as many as you need
$col1 = New-Object System.Data.DataColumn "Service Account Name",([string])
$col2 = New-Object System.Data.DataColumn "Windows Service",([string])
$col3 = New-Object System.Data.DataColumn "Hostname",([string])
# Add the Columns
$Table.columns.add($col1)
$Table.columns.add($col2)
$Table.columns.add($col3)
foreach($hostname in $hostnames){
$serviceList = Get-WmiObject -Class Win32_Service -ComputerName $hostname -Property Name, StartName, SystemName -ErrorAction Stop | Where-Object { $_.StartName -ne $null -and $_.StartName.ToUpper().Contains($tgtAcct) }
foreach ($service in $serviceList){
$Row = $Table.NewRow()
$Row."Hostname" = $hostname
$Row."Service Account Name" = $service.StartName
$servicename = $service.Name.ToString()
$Row."Windows Service" = $servicename
$Table.Rows.Add($Row)
}}
$Table | Out-GridView
$Table | Export-Csv $reportCsv -Force -NoTypeInformation
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/333063.html
