How to skip empty cells in a csv when using PowerShell to import Email Addresses? - powershell
I am trying to run the following script to import email addresses in powershell:
Import-CSV "C:\AliasesTest.csv" | foreach-object {
Set-Mailbox -Display Name $_.Name -EmailAddresses #{add=$_.Alias1,$_.Alias2,$_Alias3}}
It works fine, unless the csv has an empty cell under one of the Alias columns, at which point the following error is produced:
"The address '' is invalid: "" isn't a valid SMTP address..:
How can I construct my script to just ignore empty cells when it comes across them?
Check each property (alias) to see if it is empty, and only add the ones with values to the array inside your hash table:
Import-CSV "c:\AliasesTest.csv" | ForEach-Object {
#Save the CSV row for use in another loop later
$CSV = $_
Set-Mailbox -DisplayName $_.Name -EmailAddresses #{add = ("Alias1","Alias2","Alias3" | ForEach-Object { $Csv.$_ } | Where-Object{$_}) }
}
What that craziness does is, create a new hashtable with a key "add" that has a value of a sub expression. The sub expression has an array of property names that you want to check that it iterates over, converting each name to the value of that property, then filters out the empty ones.
Use a Where-Object filter prior to ForEach-Object like this:
Import-CSV "C:\AliasesTest.csv" | Where-Object {
$_.Alias1 -and $_.Alias2 -and $_Alias3
} | foreach-object { $_ }
If the alias' are empty strings they will be skipped. You don't have to use -and for all of them, if just one value is fine change to use -or.
Filter the aliases to take out the empty ones:
Import-CSV "C:\AliasesTest.csv" | foreach-object {
$aliases = #($_.Alias1,$_.Alias2,$_Alias3) | where-object{$_};
Set-Mailbox -Display Name $_.Name -EmailAddresses #{add=$aliases}}
Related
Powershell: delete duplicate entry in arraylist
In my Powershellscript I read some data from a csv-File in an Arraylist. In the second step I eliminate every line without the specific char: (. At the third step I want to eliminate every double entries. Example for my list: Klein, Jürgen (Klein01); salesmanagement national Klein, Jürgen (Klein01); salesmanagement national Meyer, Gerlinde (Meyer02); accounting Testuser Admin1 Müller, Kai (Muell04); support international I use the following script: $Arrayusername = New-Object System.Collections.ArrayList $NewArraylistuser = New-Object System.Collections.ArrayList $Arrayusername = Get-Content -Path "C:\Temp\User\Userlist.csv" for ($i=0; $i -le $Arrayusername.length; $i++) { if ($Arrayusername[$i] -like "*(*") { $NewArraylistuser.Add($Arrayusername_ads[$i]) } $Array_sorted = $NewArraylistuser | sort $Array_sorted | Get-Unique } But the variable $Array_sorted still has double entries. I don´t find the mistake.
Some Ideas how you could change your code: Use the existing Command to import .csv files with the Delimiter ;. Filter the output with Where-Object to only include Names with (. Select only unique objects with Select-Object, or if you want to sort the Object, use the Sort-Object with the same paramets. Something like this should work: Import-csv -Delimiter ';' -Header "Name","Position" -Path "C:\Temp\User\Userlist.csv" | Where-Object {$_.Name -like "*(*"} | Sort-Object -Unique -Property Name,Position
Find AD-user by Email
I'm trying to get users from active directory, who have a certain email address. I've got a CSV-File, which contains the emails. $data = import-csv -path .\are.csv -delimiter + foreach($i in $data) { get-aduser -filter {UserPrincipalName -like '$i.email'} } My problem is, that I don't get any output. No error, no data. When I replace $i.email with one of the email addresses, I get the right user information for the one user. So hard coding works. When I do: foreach($i in $data) { $i.email } I get a list of all the emails. What is wrong with the code?
Your variable is within single quotes thus doesn't get populated. You have to three options to fix that: Use double quotes with a sub expression $(): UserPrincipalName -like "$($i.email)" Just omit the quotes: UserPrincipalName -like $i.email And finally you could use a format string (even with single quotes): UserPrincipalName -like ('{0}' -f $i.email) Here is an example to demonstrate what actual value gets passed using the Write-Host cmdlet: $data = #' email, id myname#web.de, 1 '# | convertfrom-csv foreach($i in $data) { Write-Host '$i.email' # This is your current approach Write-Host "$($i.email)" Write-Host $i.email Write-Host ('{0}' -f $i.email) } Output: $i.email # This is the output of your current approach myname#web.de myname#web.de myname#web.de
Append existing column in csv by matching values with array and with condition
I will do my best to break this down as simply as I can. what I have so far that is working: Currently I have two csv files... test1.csv test1ColumnN,test1ColumnI,test1ColumnD,selectDomainOne,selectDomainTwo,selectDomainThree asdf,asdf,asdf,,, nValue1,iValue1,dValue1,sValue1,, qwer,asdf,zxcv,,, nValue2,iValue2,dValue2,,, qwer,zxcv,asdf,lkjh,, nValue3,iValue3,dValue3,sValue3,, zxcv,qwer,asdf,,poiu, nValue1,iValue1,dValue1,,sValue1, nValue4,iValue4,dValue4,,sValue4, asdf,qwer,zxcv,fghj,mnbv, nValue5,iValue5,dValue5,,, asdf,cvbn,erty,,,uytr nValue7,iValue7,dValue7,,,sValue7 nValue8,iValue8,dValue8,,,sValue8 nValue9,iValue9,dValue9,,,sValue9 qwer,asdf,zxcv,poiu,lkjh,mnbv test2.csv DomainCatagories,test2ColumnS,test2ColumnA,test2ColumnN,test2ColumnI,test2ColumnD DomainOne,sValue1,aValue1,nValue1,,dValueN DomainOne,sValue2,aValue2,,iValue2,dValue2 DomainOne,sValue3,aValue2,nValue3,iValue3,dValue3 DomainTwo,sValue1,aValue2,,iValue1,dValueN DomainTwo,sValue4,aValue1,nValue4,,dValueN DomainTwo,sValue5,aValue1,nValue5,iValue5,dValue5 DomainThree,sValue7,aValue2,nValue7,iValue7,dValue7 DomainThree,sValue8,aValue1,nValue8,iValue8,dValue8 DomainThree,sValue9,aValue2,nValue9,iValue9,dValue9 Now I want to add a column (inside test2.csv) to match the sValue# from both test1.csv and test2.csv with the condition of ($_.DomainCatagories='DomainOne' from test2.csv) and ($_.selectDomainOne from test1.csv) To do this, I am using the following code... #Create Column $domainNameOne = #{} $domainNameOne = Import-Csv 'C:\Scripts\Tests\test1.csv' | Where-Object {$_.selectDomainOne} | Select-Object -Expand 'selectDomainOne' (Import-Csv 'C:\Scripts\Tests\test2.csv') | Select-Object -Property *, #{n='Test1sValues';e={ if($_.DomainCatagories -eq 'DomainOne'){ if(($domainNameOne -contains $_.test2ColumnS) -and ($_.test2ColumnS)){ $_.test2ColumnS } Else { 'Not found in test1' }}}} | Export-Csv "C:\Scripts\Tests\test2-Temp" -NoType Move-Item "C:\Scripts\Tests\test2-Temp" 'C:\Scripts\Tests\test2.csv' -Force After the code is run, I get the following test2.csv (isCorrect)... "DomainCatagories","test2ColumnS","test2ColumnA","test2ColumnN","test2ColumnI","test2ColumnD","Test1sValues" "DomainOne","sValue1","aValue1","nValue1","","dValueN","sValue1" "DomainOne","sValue2","aValue2","","iValue2","dValue2","Not found in test1" "DomainOne","sValue3","aValue2","nValue3","iValue3","dValue3","sValue3" "DomainTwo","sValue1","aValue2","","iValue1","dValueN","" "DomainTwo","sValue4","aValue1","nValue4","","dValueN","" "DomainTwo","sValue5","aValue1","nValue5","iValue5","dValue5","" "DomainThree","sValue7","aValue2","nValue7","iValue7","dValue7","" "DomainThree","sValue8","aValue1","nValue8","iValue8","dValue8","" "DomainThree","sValue9","aValue2","nValue9","iValue9","dValue9","" What I have that is not working: Next I run the following code... #Append Column $domainNameThree = #{} $domainNameThree = Import-Csv 'C:\Scripts\Tests\test1.csv' | Where-Object {$_.selectDomainThree} | Select-Object -Expand 'selectDomainThree' (Import-Csv 'C:\Scripts\Tests\test2.csv') | % { if($_.DomainCatagories -eq 'DomainThree'){ if(($domainNameThree -contains $_.test2ColumnS) -and ($_.test2ColumnS)){ $_.Test1sValues = $_.test2ColumnS } Else { $_.Test1sValues = 'Not found in test1' }}} | Export-Csv "C:\Scripts\Tests\test2-Temp" -NoType Move-Item "C:\Scripts\Tests\test2-Temp" 'C:\Scripts\Tests\test2.csv' -Force Instead of adding the values in the correct rows, it completely blanks out the whole file and saves it as an empty file. End Goal What I want the code to produce, is this (notice values filled in on last 3 rows in the last column)... "DomainCatagories","test2ColumnS","test2ColumnA","test2ColumnN","test2ColumnI","test2ColumnD","Test1sValues" "DomainOne","sValue1","aValue1","nValue1","","dValueN","sValue1" "DomainOne","sValue2","aValue2","","iValue2","dValue2","Not found in test1" "DomainOne","sValue3","aValue2","nValue3","iValue3","dValue3","sValue3" "DomainTwo","sValue1","aValue2","","iValue1","dValueN","" "DomainTwo","sValue4","aValue1","nValue4","","dValueN","" "DomainTwo","sValue5","aValue1","nValue5","iValue5","dValue5","" "DomainThree","sValue7","aValue2","nValue7","iValue7","dValue7","sValue7" "DomainThree","sValue8","aValue1","nValue8","iValue8","dValue8","sValue8" "DomainThree","sValue9","aValue2","nValue9","iValue9","dValue9","sValue9" What am I doing wrong in that 2nd code snippet?
The example you show from What I have that is not working: is missing a key portion. Export-Csv will take everything piped into it to populate the CSV but you are not providing any. Problem is that you are not passing anything through the pipe. Merely just updating one property. The simplest thing to do is add $_ after the if statement. Or you could just use a calculated property which you have done before in another one of your questions. The example below from Compare dates with different formats in csv file even uses an if statement. Import-Csv $csvFile | Select-Object *, #{n='MatchDates';e={ if((([datetime]$_.Date1).Date -eq $_.Date3) -and (([datetime]$_.Date2).Date -eq $_.Date3) -and (([datetime]$_.Date1).Date -eq $_.Date2)){ 'Match Found' }Else{ 'No Match Found' }}} | Export-Csv "$csvFile-results.csv" -NoTypeInformation -Force
Powershell using where-object
I am using Powershell and am having trouble with the Where-Object cmdlet. I currently select * and then want to only output when a field is equal to Alabama. This field could be under any column, not just one. This is what I have: select * | where {$_.state_name -eq 'Alabama'} . This works for state_name, but i cant get all columns without doing them individually. I've tried where{$_ -eq....} but that doesn't work.
Kind of a hack, but: select * | where {($_ | ConvertTo-Csv -NoTypeInformation)[1] -like '*"Alabama"*'}
You have to iterate over all object's properties and check if it contains word 'Alabama'. Example: # Import CSV file and feed it to the pipeline Import-Csv -Path .\My.csv | # For each object ForEach-Object { # Psobject.Properties returns all object properties # (Psobject.Properties).Value returns only properties' values # -contains operator checks if array of values contains exact string 'Alabama' # You can also use -like operator with wildcards, i.e. -like '*labama' if(($_.PSObject.Properties).Value -contains 'Alabama') { # If any of the object properties contain word 'Alabama', # write it to the pipeline, else do nothing. $_ } }
Issues with Powershell Import-CSV
Main Script $Computers = Get-Content .\computers.txt If ( test-path .\log.txt ) { $Log_Successful = Import-CSV .\log.txt | Where-Object {$_.Result -eq "Succesful"} } ELSE { Add-Content "Computer Name,Is On,Attempts,Result,Time,Date" } $Log_Successful | format-table -autosize Issues: Log_Successful."Computer Name" works fine, but if i change 4 to read as the following $Log_Successful = Import-CSV .\log.txt | Where-Object {$_.Result -eq "Failed"} Log_Successful."Computer Name" no longer works... Any ideas why? Dataset Computer Name,Is On,Attempts,Result,Time,Date 52qkkgw-94210jv,False,1,Failed,9:48 AM,10/28/2012 HELLBOMBS-PC,False,1,Successful,9:48 AM,10/28/2012 52qkkgw-94210dv,False,1,Failed,9:48 AM,10/28/2012
In case of "Successful" a single object is returned. It contains the property "Computer Name". In case of "Failed" an array of two objects is returned. It (the array itself) does not contain the property "Computer Name". In PowerShell v3 in some cases it is possible to use notation $array.SomePropertyOfContainedObject but in PowerShell v2 it is an error always. That is what you probably see. You should iterate through the array of result objects, e.g. foreach($log in $Log_Successful) {...} and access properties of the $log objects. And the last tip. In order to ensure that the result of Import-Csv call is always an array (not null or a single object) use the #() operator. The code after fixes would be: $logs = #(Import-Csv ... | where ...) # $logs is an array, e.g. you can use $logs.Count # process logs foreach($log in $logs) { # use $log."Computer Name" }
I'm not sure if this is the problem but you have a typo, in Where-Object you compare against "Succesful" and the value in the file is "Successful" (missing 's'). Anyway, what's not working?