我试图弄清楚如何从具有适当列的PowerShell对象创建.csv。我想创建一个具有三列(用户ID,国家/地区,计数)的.csv文件。还需要按用户ID排序,然后按国家(A到Z)排序。在下面的示例代码中,我希望输出像这样:
User ID, Country, Count Bob, China, 2 Joe, Canada, 1 Joe, United States, 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”和“国家/地区”位于以下同一列中:
"User ID, Country","Count" "Joe, United States","1" "Bob, China","2" "Joe, Canada","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文件,其中包含一堆电子邮件地址和按国家/地区进行的失败登录尝试。最后一行用于计算每个电子邮件地址来自每个公司的失败尝试次数。这就是问题所在。
答案 0 :(得分:1)
我已简化了您的问题陈述,以便一次解决一个问题。
我着手解决一个简单的问题,即从中生成所需的输出CSV文件
您输入的CSV文件。我使用记事本而不是Powershell创建了输入文件。
这是我想出的:
<# Summarizes log by user and country. #>
Import-csv logfile.csv |
Sort-Object UserID, Country |
Group-Object UserID, Country |
foreach { $b = $_.name -split ', '
[PSCustomobject] @{UserID = $b[0]; Country= $b[1]; Count=$_.count}}|
Export-Csv summary.csv
Import-Csv logfile.csv | Format-table
Import-Csv summary.csv | Format-table
最后两个步骤仅显示输入和输出CSV文件。这就是我运行它时的样子。
UserID Country
------ -------
Joe United States
Bob China
Bob China
Joe Canada
UserID Country Count
------ ------- -----
Bob China 2
Joe Canada 1
Joe United States 1
答案 1 :(得分:0)
如我的评论中所述,您将需要两个计算出的属性才能再次拆分Name。
(Import-Csv $path) | Group-Object 'User ID',Country -NoElement |
Select-Object @{n='UserID';e={($_.Name -split ', ')[0]}},
@{n='Country';e={($_.Name -split ', ')[1]}},
Count | Export-Csv $Path -NoTypeInformation
这将产生与Walter Mitty解决方案相同的输出。
答案 2 :(得分:-1)
当使用cmdlet中内置的availabe处理CSV数据时,您可以使工作变得更加轻松:
$path = 'C:\test\test.csv'
$Data = @'
UserID,Country,Count
Bob,China,2
Joe,Canada,1
Joe,United States,1
'@
ConvertFrom-Csv -Delimiter ',' -InputObject $Data -OutVariable CSVData
$CSVData | Export-Csv -Path $path -NoTypeInformation -Delimiter ','
您只需根据需要完全构建数据,然后将其转换或导出一次即可。