【发布时间】:2019-02-09 14:26:12
【问题描述】:
我试图弄清楚如何从具有适当列的 PowerShell 对象创建 .csv。我想创建一个包含三列(用户 ID、国家/地区、计数)的 .csv 文件。它还需要先按用户 ID 排序,然后按国家/地区(A 到 Z)。在下面的示例代码中,我希望输出是这样的:
用户 ID、国家/地区、计数 鲍勃,中国,2 乔,加拿大,1 乔,美国,1
$path = "C:\test\test.csv"
Set-Content -Path $path -Value “UserId, Country”
Add-Content -Path $path -Value "Joe, United States", "Bob, China", "Bob, China", "Joe, Canada"
(Import-Csv -Path $path) | Group-Object -Property UserID, Country -NoElement | Select-Object * -ExcludeProperty Values, Group | Select-Object @{Name="User ID, Country";Expression={$_.Name}}, Count | Export-Csv -Path $path -NoTypeInformation -Force
Get-Content -Path $path
不幸的是,当我运行此程序时,用户 ID 和国家/地区如下所示:
"用户 ID,国家/地区","计数" "乔,美国","1" “鲍勃,中国”,“2” "乔,加拿大","1"
我相信问题源于Select-Object @{Name="User ID, Country";Expression={$_.Name}}。我怎样才能让它按照上面的要求排列在三列中?顺便说一句,我不完全理解问题代码的语法。如果您能解释一下 @{Name="User ID, Country";Expression={$_.Name}} 的作用,我将不胜感激。
编辑 这是我的实际代码,以防万一这有助于解决问题。
Set-ExecutionPolicy RemoteSigned
$lastMonth = (get-date).AddMonths(-1)
$startDate = get-date -year $lastMonth.Year -month $lastMonth.Month -day 1
$endDate = ($startDate).AddMonths(1).AddSeconds(-1)
$operation = UserLoginFailed
$path = "C:\Failed Logins $($lastMonth.ToString("yyyy_MM")).csv"
Set-Content -Path $path -Value “UserId, Country”
Function Connect-EXOnline {
$credentials = Get-Credential -Credential $credential
$Session = New-PSSession -ConnectionUri https://outlook.office365.com/powershell-liveid/ `
-ConfigurationName Microsoft.Exchange -Credential $credentials `
-Authentication Basic -AllowRedirection
Import-PSSession $Session -AllowClobber
}
$credential = Get-Credential
Connect-EXOnline
$Logs = @()
do {
$logs += Search-unifiedAuditLog -SessionCommand ReturnLargeSet -SessionId "UALSearch" -ResultSize 5000 -StartDate $startDate -EndDate $endDate -Operations $operation
}while ($Logs.count % 5000 -eq 0 -and $logs.count -ne 0)
$userIds = $logs.userIds | Sort-Object -Unique
foreach ($userId in $userIds) {
$ips = @()
$searchResult = ($logs | Where-Object {$_.userIds -contains $userId}).auditdata | ConvertFrom-Json -ErrorAction SilentlyContinue
$ips = $searchResult.clientip
foreach ($ip in $ips) {
$mergedObject = @{}
$singleResult = $searchResult | Where-Object {$_.clientip -contains $ip} | Select-Object -First 1
Start-sleep -m 400
$ipresult = Invoke-restmethod -method get -uri http://ip-api.com/json/$ip
$UserAgent = $singleResult.extendedproperties.value[0]
$singleResultProperties = $singleResult | Get-Member -MemberType NoteProperty
foreach ($property in $singleResultProperties) {
if ($property.Definition -match "object") {
$string = $singleResult.($property.Name) | ConvertTo-Json -Depth 10
$mergedObject | Add-Member -Name $property.Name -Value $string -MemberType NoteProperty
}
else {$mergedObject | Add-Member -Name $property.Name -Value $singleResult.($property.Name) -MemberType NoteProperty}
}
$property = $null
$ipProperties = $ipresult | get-member -MemberType NoteProperty
foreach ($property in $ipProperties) {
$mergedObject | Add-Member -Name $property.Name -Value $ipresult.($property.Name) -MemberType NoteProperty
}
$mergedObject | Select-Object UserId, Country | Export-Csv $path -Append -NoTypeInformation
}
}
(Import-Csv -Path $path) | Group-Object -Property UserID, Country -NoElement | Select-Object * -ExcludeProperty Values, Group | Select-Object @{Name="User ID, Country";Expression={$_.Name}}, Count | Export-Csv -Path $path -NoTypeInformation
基本上,我将有一个 .csv 文件,其中包含一堆电子邮件地址和按国家/地区分类的失败登录尝试。最后一行用于计算每个电子邮件地址从每个公司收到的失败尝试次数。这就是问题所在。
【问题讨论】:
-
Group-Object和 -NoElement 将只留下属性 Count,Name ,其中 Name 由 UserId 和 Country 组成,用逗号分隔。您需要 两个 计算属性来再次拆分它们。 -
你已经知道多少powershell了?特别是,您是否曾经在管道右侧使用过 Export-Csv?
-
这是一个愚蠢的例子:Get-Process |导出-Csv myfile.csv
-
@LotPings 这是有道理的。我做了一些关于如何做到这一点的搜索,但我找不到任何东西。
-
@WalterMitty 我对 PowerShell 很陌生。但是,我在管道的右侧使用了 Export-Csv。