Home > Blockchain >  How to fix A null key is not allowed in a hash literal in PowerShell
How to fix A null key is not allowed in a hash literal in PowerShell

Time:12-06

I been following this Microsoft doc https://docs.microsoft.com/en-us/powershell/module/exchange/search-unifiedauditlog?view=exchange-ps and I'm trying to write a PowerShell Script that download Audit Log. So far everything is going well but I'm just wondering how can I read User Id from my csv file instead of having a user Id directly in my script?.

This is how my CSV file look right now.

C:\AuditLogSearch\Reference\User.csv

     Name       Email             Id      
................................
1.   Ronaldo    [email protected]   KLIEKN
2.   Messi      [email protected]     LEK89K
3.   LeBron     [email protected]    IKNLM9

I was hard coding like this in the script and it's working fine but

$Global:user = "KLIEKN", "LEK89K", "IKNLM9",

Search-UnifiedAuditLog -SessionId $sessionID -SessionCommand ReturnLargeSet -UserIds $user

I don't think that'll be good idea so I try to do read it from my CSV file like this

$Global:userPath = "C:\AuditLogSearch\Reference\User.csv"

function Log-Search {

  Import-Csv $userPath | ForEach-Object  -Property @{
        $userId = $($_.Id) 
    }  

Search-UnifiedAuditLog -SessionId $sessionID -SessionCommand ReturnLargeSet -UserIds $userId
}

but I'm getting this error

A null key is not allowed in a hash literal.

I'll be really appreciated any help or suggestion.

CodePudding user response:

{} defines a [ScriptBlock] — which is what you'd pass to the ForEach-Object cmdlet to be invoked for each element — whereas @{} defines a [Hashtable]. $userId is $null because you have not assigned a value, so where you have...

@{
    $userId = $($_.Id) 
}

...you are trying to define a [Hashtable] with an element with a key of $null, hence the error.

There is also no such -Property parameter of ForEach-Object, so when you remove "-Property @", you end up with a valid script...

Import-Csv $userPath | ForEach-Object {
    $userId = $($_.Id) 
}

This is reading your CSV file but not yet passing the data to your Search-UnifiedAuditLog call. There are several ways to retrieve the Id field of each CSV record, but the shortest transformation from the previous snippet would be...

Import-Csv $userPath | ForEach-Object {
    $_.Id
}

...which can be rewritten using the -MemberName parameter...

Import-Csv $userPath | ForEach-Object -MemberName Id

...and then all that's left is to store the pipeline results in $userId...

$userId = Import-Csv $userPath | ForEach-Object -MemberName Id

By the way, the CSV data you posted cannot be readily parsed by Import-Csv. If possible, save your data without the second line and using comma or tab as the delimiter (the latter being read with Import-Csv ... -Delimiter "`t"); otherwise, the script will have to do some manipulation before it can read the data.

CodePudding user response:

Try this perhaps?

$userId=@()
Import-Csv $userPath | ForEach-Object {
    $userId  = $_.Id
}

or

$userId = Import-Csv $userPath | Select-Object -ExpandProperty Id
  • Related