0
votes

Format CSV à partir de l'objet

J'essaie de déterminer comment créer un fichier .csv à partir d'un objet PowerShell qui possède les colonnes appropriées. Je souhaite créer un fichier .csv avec trois colonnes (ID utilisateur, pays, compte). Il doit également trier par l'ID utilisateur, puis le pays (A à Z). Dans le code exemple ci-dessous, je veux que la sortie soit comme celle-ci: xxx pré>

p>

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


6 commentaires

Groupe-Object avec -NOElement vous laissera uniquement le nombre de propriétés, le nom où le nom est composé d'UserID et de pays délimité avec un espace des virgules. Vous aurez besoin de deux propriétés calculées pour les diviser à nouveau.


Combien de PowerShell connaissez-vous déjà? En particulier, avez-vous déjà utilisé Export-CSV sur le côté droit d'un pipeline?


Voici un exemple idiot: Get-Process | Export-csv myfile.csv


@ Gotpings qui a du sens. J'ai fait un peu de recherche sur la façon de faire cela, et je ne pouvais rien trouver.


@Waltermitty Je suis très nouveau quand il s'agit de PowerShell. J'ai utilisé Export-CSV sur le côté droit d'un pipeline.


@Lotpings je viens de trouver docs.microsoft.com/en-us/previous-versions/windows/it-pro/... qui traite des propriétés calculées! Ça a marché comme sur des roulettes. Merci!


3 Réponses :


-1
votes

Vous pouvez rendre votre vie beaucoup plus facile lorsque vous utilisez la disponabe intégrée dans des câbles CMDlets pour les données CSV, telles que ceci: xxx

Vous construisez simplement vos données à mesure que vous en avez besoin complètement et que vous le convertissez ou Exportez-le en une fois.


2 commentaires

Pas sûr si cela est applicable. Je vais éditer mon message pour contenir le code que je travaille réellement.


WOW, c'est un gros morceau de code déroutant. Vous pouvez faire un pas en arrière et prendre un peu de temps pour apprendre les bases de PowerShell. Vous essayez de créer de manière itérative un fichier CSV étape par étape ou ligne par ligne. Ce n'est pas la façon dont nous faisons des choses dans PowerShell. Vous devez créer toutes les données que vous souhaitez exporter d'abord et les exporter en une fois lorsque vous avez terminé.



1
votes

J'ai simplifié votre énoncé de problème afin de lutter contre un problème à la fois.
Je suis parti pour résoudre le problème simple de la production du fichier CSV de sortie que vous voulez de Le fichier CSV d'entrée que vous avez indiqué. J'ai créé le fichier d'entrée avec le bloc-notes, au lieu de avec PowerShell.

Voici ce que je suis venu avec: xxx

Les deux dernières étapes visent simplement l'entrée et les fichiers CSV de sortie. C'est ce à quoi il ressemblait quand je l'ai manqué. xxx


1 commentaires

L'outil principal utilisé pour rendre cette réponse simple et lisible est le pipeline. Si vous êtes nouveau à PowerShell et aux pipelines, prenez le temps d'apprendre à utiliser des pipelines à bon avantage (et quand ne pas essayer de les utiliser). Même si vous avez utilisé des pipelines dans un autre environnement, vous pouvez constater que les pipelines Powershell sont plus puissants que prévu.



0
votes

Comme mentionné dans mon commentaire, vous aurez besoin deux propriétés calculées pour scinder le nom. xxx

Cela donnera la même sortie que la solution de Walter Mitty.


0 commentaires