run powershell command using csv as input - powershell

I have a csv that looks like
Name, email, address
Name, email, address
Name, email, address
I am wanting to run
New-Mailbox -Name "*Name*" -WindowsLiveID *email* -ImportLiveId
(where *x* is replaced by the value from the csv).
on each line in the csv file.
How can I do this?

$csv = Import-Csv c:\path\to\your.csv
foreach ($line in $csv) {
New-Mailbox -Name $line.Name -WindowsLiveID $line.Email -ImportLiveId
}
First line of csv has to be something like Name,Email,Address
If you cannot have the header in the CSV, you can also have:
$csv = Import-Csv c:\path\to\your.csv -Header #("Name","Email","Address")
-Header doesn't modify the csv file in any way.

import-csv .\file.csv -header ("first","second","third") | foreach{New-Mailbox -Name $_.first -WindowsLiveID $_.second -ImportLiveId}

This is some of the most useful information I have seen yet - it just made my job so much easier!!!
Combining Netapp commands:
get volumes from a controller, get snapshot schedule for said volumes, and export to a csv:
get-navol | Get-NaSnapshotSchedule | Export-Csv -path d:\something.csv
Import the csv reading in current values and assigning each column a label.
For each object, create a new schedule by RE-USING 4 of the 5 available columns/data fields
import-csv d:\something.csv -header ("label1","label2","label3","label4","label5") | foreach {Set-naSnapshotschedule $.label1 -Weeks $.label2 -Days $.label3 -Hours $.label4 -Whichhours "1,2,3,4,5"}
EXCELLENT STUFF!!!
Please note that the "Labels" should have an underscore - for whatever reason it isn't reflecting in the page so Dollar($)Underscore(_)Dot(.)Label

Related

Powershell - Compare CSV 1 to CSV 2 and then update CSV1

I am not looking for a writing service but please can someone point me in the right direction as I am completely at a lost as to how to proceed.
Overview
I have a CSV which contains a lot of data, some of which comes from a script and some in manually imputed. I can run the script and get new data which is good. What I would like to do is find a way to compare the orginal CSV 1 to the new CSV 2 and update CSV 1.
Code I currently have
$Vips_to_check = #{}
Import-Csv 'C:\Users\user\Documents\20221201\Netscaler VIPs per Cluster_edited - Raw Data.csv' |
Where-Object {$_.PRD -match "No PRD code from VIP IP and VIP has no backend IPs" -or
$_.PRD -match "No PRD code found from VIP or backend IPs" -or
$_.PRD -match "No PRD code found from backend IPs" -and
$_.ipv46 -notcontains "0.0.0.0"} |
$Results_from_PIM = Import-Csv 'C:\Users\user\Documents\20221201\VIP-Owners_edited.csv'
Both of the CSV's have the same headers and layout which is good. I assume!
CSV 1
Name IPV46 Port Curstate Suggested PRD Display Name tech Owner Slack Channel Support Email
name 1 1.2.3.4 8080 Down No No No No No No No
CSV 2
Name IPV46 Port Curstate Suggested PRD Display Name tech Owner Slack Channel Support Email
name 1 1.2.3.4 8080 Down No PRD123 TMOL Gary TMOL Support Support#email.com nsr.sys
I would guess at creating a hashtable but I just can't seem to get my head around the format of them. I tried
$ht = $Results_from_pim #{}
$_.Name = (cant figure out how to reference the cell)
$_.PRD =
$_.("Display Name")
$_.("Tech Owner")
Once I have the data in the hash table how do I overwrite the CSV 1 data?
Any points or guides would be great. I have tried reading up on https://learn.microsoft.com/en-gb/powershell/scripting/learn/deep-dives/everything-about-hashtable?view=powershell-7.3 and https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-pscustomobject?view=powershell-7.3
But that left me even more confused.
At the moment the difference is only 4 or 5 entries and it would of been quicker for me to manually edit in excel but as this script gets larger I can see it being more time consuming to do manually.
As always thank you.
UPDATE
$ht = #{}
foreach ($item in $Results_from_PIM) {
"name = $($item.name)"
"prd = $($item.PRD)"
"Display Name = $($item.'Display Name')"
"Tech Owner = $($item.'Tech Owner')"
"Slack Channel = $($item.'Slack Channel')"
"Support Email = $($Item.'Support Email')"
}
I have created the hash table that I wanted from the CSV 2. Just got to get it to compare to CSV 1.
Update 2
Further to #theo request I have adjusted the question. Also to clarify When I want to merge the CSV it is based on matching the Name, IPV46 and Port on both CSV and then moving the updated data from CSV2 into CSV1.
You can do that with the code below (no extra module needed):
$csv1 = 'C:\Users\user\Documents\20221201\Netscaler VIPs per Cluster_edited - Raw Data.csv'
$csv2 = 'C:\Users\user\Documents\20221201\VIP-Owners_edited.csv'
$Results_from_PIM = Import-Csv -Path $csv2
$newData = Import-Csv -Path $csv1 | ForEach-Object {
$search = $_.Name + $_.IPV46 + $_.Port # combine these fields into a single string
$compare = $Results_from_PIM | Where-Object { ($_.Name + $_.IPV46 + $_.Port) -eq $search }
if ($compare) {
# output the result from csv2
$compare
}
else {
# output the original row from csv1
$_
}
}
# now you can save the updated data to a new file or overwrite csv1 if you like
$csv3 = 'C:\Users\user\Documents\20221201\VIP-Owners_Updated.csv'
$newData | Export-Csv -Path $csv3 -NoTypeInformation
P.S. Please read about Formatting
After being direct to In PowerShell, what's the best way to join two tables into one? by #jdweng. I performed the following which seems to have meet my requirements
Install-Module -Name JoinModule -Scope CurrentUser
$Vips_to_check = Import-Csv 'C:\Users\user\Documents\20221201\Netscaler VIPs per Cluster - Raw Data.csv'
$Results_from_PIM = Import-Csv 'C:\Users\user\Documents\20221201\VIP-Owners.csv'
$Vips_to_check | Update-Object $Results_from_PIM -On name, Ipv46, port | Export-Csv 'C:\Users\user\Documents\20221201\Final_data1.csv'
Going to do further testing with larger data sets but appears to work as required.

Using Powershell, how can I export and delete csv rows, where a particular value is *not found* in a *different* csv?

I have two files. One is called allper.csv
institutiongroup,studentid,iscomplete
institutionId=22343,123,FALSE
institutionId=22343,456,FALSE
institutionId=22343,789,FALSE
The other one is called actswithpersons.csv
abc,123;456
def,456
ghi,123
jkl,123;456
Note: The actswithpersons.csv does not have headers - they are going to be added in later via an excel power query so don't want them in there now. The actswithpersons csv columns are delimited with commas - there are only two columns, and the second one contains multiple personids - again Excel will deal with this later.
I want to remove all rows from allper.csv where the personid doesn't appear in actswithpersons.csv, and export them to another csv. So in the desired outcome, allper.csv would look like this
institutiongroup,studentid,iscomplete
institutionId=22343,123,FALSE
institutionId=22343,456,FALSE
and the export.csv would look like this
institutiongroup,studentid,iscomplete
institutionId=22343,789,FALSE
I've got as far as the below, which will put into the shell whether the personid is found in the actswithpersons.csv file.
$donestuff = (Get-Content .\ActsWithpersons.csv | ConvertFrom-Csv); $ids=(Import-Csv .\allper.csv);foreach($id in $ids.personid) {echo $id;if($donestuff -like "*$id*" )
{
echo 'Contains String'
}
else
{
echo 'Does not contain String'
}}
However, I'm not sure how to go the last step, and export & remove the unwanted rows from allper.csv
I've tried (among many things)
$donestuff = (Get-Content .\ActsWithpersons.csv | ConvertFrom-Csv);
Import-Csv .\allper.csv |
Where-Object {$donestuff -notlike $_.personid} |
Export-Csv -Path export.csv -NoTypeInformation
This took a really long time and left me with an empty csv. So, if you can give any guidance, please help.
Since your actswithpersons.csv doesn't have headers, in order for you to import as csv, you can specify the -Header parameter in either Import-Csv or ConvertFrom-Csv; with the former cmdlet being the better solution.
With that said, you can use any header name for those 2 columns then filter by the given column name (ID in this case) after your import of allper.csv using Where-Object:
$awp = (Import-Csv -Path '.\actswithpersons.csv' -Header 'blah','ID').ID.Split(';')
Import-Csv -Path '.\allper.csv' | Where-Object -Property 'Studentid' -notin $awp
This should give you:
institutiongroup studentid iscomplete
---------------- --------- ----------
institutionId=22343 789 FALSE
If you're looking to do it with Get-Content you can split by the delimiters of , and ;. This should give you just a single row of values which you can then compare the entirety of variable ($awp) using the same filter as above which will give you the same results:
$awp = (Get-Content -Path '.\actswithpersons.csv') -split ",|;"
Import-Csv -Path '.\allper.csv' | Where-Object -Property 'Studentid' -notin $awp

Powershell - Finding the output of get-contents and searching for all occurrences in another file using wild cards

I'm trying to get the output of two separate files although I'm stuck on the wild card or contains select-string search from file A (Names) in file B (name-rank).
The contents of file A is:
adam
george
william
assa
kate
mark
The contents of file B is:
12-march-2020,Mark-1
12-march-2020,Mark-2
12-march-2020,Mark-3
12-march-2020,william-4
12-march-2020,william-2
12-march-2020,william-7
12-march-2020,kate-54
12-march-2020,kate-12
12-march-2020,kate-44
And I need to match on every occurrence of the names after the '-' so my ordered output should look like this which is a combination of both files as the output:
mark
Mark-1
Mark-2
Mark-3
william
william-2
william-4
william-7
Kate
kate-12
kate-44
kate-54
So far I only have the following and I'd be grateful for any pointers or assistance please.
import-csv (c:\temp\names.csv) |
select-string -simplematch (import-csv c:\temp\names-rank.csv -header "Date", "RankedName" | select RankedName) |
set-content c:\temp\names-and-ranks.csv
I imagine the select-string isn't going to be enough and I need to write a loop instead.
The data you give in the example does not give you much to work with, and the desired output is not that intuitive, most of the time with Powershell you would like to combine the data in to a much richer output at the end.
But anyway, with what is given here and what you want, the code bellow will get what you need, I have left comments in the code for you
$pathDir='C:\Users\myUser\Downloads\trash'
$names="$pathDir\names.csv"
$namesRank="$pathDir\names-rank.csv"
$nameImport = Import-Csv -Path $names -Header names
$nameRankImport= Import-Csv -Path $namesRank -Header date,rankName
#create an empty array to collect the result
$list=#()
foreach($name in $nameImport){
#get all the match names
$match=$nameRankImport.RankName -like "$($name.names)*"
#add the name from the First list
$list+=($name.names)
#if there are any matches, add them too
if($match){
$list+=$match
}
}
#Because its a one column string, Export-CSV will now show us what we want
$list | Set-Content -Path "$pathDir\names-and-ranks.csv" -Force
For this I would use a combination of Group-Object and Where-Object to first group all "RankedName" items by the name before the dash, then filter on those names to be part of the names we got from the 'names.csv' file and output the properties you need.
# read the names from the file as string array
$names = Get-Content -Path 'c:\temp\names.csv' # just a list of names, so really not a CSV
# import the CSV file and loop through
Import-Csv -Path 'c:\temp\names-rank.csv' -Header "Date", "RankedName" |
Group-Object { ($_.RankedName -split '-')[0] } | # group on the name before the dash in the 'RankedName' property
Where-Object { $_.Name -in $names } | # use only the groups that have a name that can be found in the $names array
ForEach-Object {
$_.Name # output the group name (which is one of the $names)
$_.Group.RankedName -join [environment]::NewLine # output the group's 'RankedName' property joined with a newline
} |
Set-Content -Path 'c:\temp\names-and-ranks.csv'
Output:
Mark
Mark-1
Mark-2
Mark-3
william
william-4
william-2
william-7
kate
kate-54
kate-12
kate-44

Updating Active directory DN in csv records with Powershell

I'm completely stuck on how to update multiple rows in a CSV file with new values.. the issue is as follows, I import an active directory csv export file into my powershell which has roughly 500 users, like so:
$Users = Import-CSV "C:\Users\administrator\userExport.csv"
I then need to update the DN column so that they have the new active directory structure on the new domain
Current structure:
DN:
-----------------
CN=John Smith,OU=Users,DC=XTR,DC=ORG
Required new domain structure
DN:
-----------------
CN=John Smith,OU=Users,OU=Administration,DC=RTS,DC=LIVE,DC=LOCAL
The trouble is I have no idea how I can sequentially go through the entries in this CSV files to update only the necessary elements of the entry via powershell, any help with this would be much appreciated.
Sample line from csv file:
DN objectClass instanceType
-- ------------ ------------
CN=John Smith,OU=Users,DC=XTR,DC=ORG user 4
Apologies, I know how vague the request is but I'm sure there must be an elegant way of doing this but my powershell knowledge is extremely limited.
Thanks for your time.
Import-Csv will convert each row in the CSV to an object with properties corresponding to the column headers and the column value of the current row. This makes them easy to manipulate:
$Users = Import-CSV "C:\Users\administrator\userExport.csv"
$Users |ForEach-Object {
# Update DN column value
$_.DN = $_.DN -replace ',DC=XTR,DC=ORG$', ',OU=Administration,DC=RTS,DC=LIVE,DC=LOCAL'
# Output modified object
$_
} |Export-Csv C:\Users\administrator\userExportModified.csv -NoTypeInformation
You should put your CSV sample "as is", and not trying to format it. How can we know if the CSV is well-formed ?
I am trying to answer anyway, based on a well-formed CSV, with default delimiter (comma) :
Import-CSV "C:\Users\administrator\sourceUsers.csv" | ForEach {
$_.DN = $_.DN -replace "OU=Users,DC=XTR,DC=ORG","OU=Users,OU=Administration,DC=RTS,DC=LIVE,DC=LOCAL"
# ^
# Are you sure it is actually 'OU' here and not 'CN'
$_
} | Export-Csv "C:\Users\administrator\destinationUsers.csv" -NoTypeInformation -Enconding UTF8
If there is another delimiter, eg semi colon :
Import-CSV "C:\Users\administrator\sourceUsers.csv" -Delimiter ';' | ForEach {
$_.DN = $_.DN -replace "OU=Users,DC=XTR,DC=ORG","OU=Users,OU=Administration,DC=RTS,DC=LIVE,DC=LOCAL"
# ^
# Are you sure it is actually 'OU' here and not 'CN'
$_
} | Export-Csv "C:\Users\administrator\destinationUsers.csv" -NoTypeInformation -Enconding UTF8
Edit :
Mathias answered during I was typing my own one :), I keep it only because of my remarks about CSV and the 'OU=Users...'

Get-MsolDevice RegisteredOwners export to CSV fails

I've written a simple script that is attempting to use the input from a source CSV file containing ObjectID's in a column and then exporting the following information; DisplayName, DeviceTrustType, RegisteredOwners, ApproximateLastLoginTimeStamp using the Get-MsolDevice command.
Here's the code I've got so far:
Connect-MsolService
Connect-AzureAD
Get-AzureADDevice -All $True | Select ObjectID | Export-Csv "C:\temp\Project\IntuneDevices\AllAADObjectIDs.csv" -noType
$allobjects = Import-Csv "C:\temp\Project\IntuneDevices\AllAADObjectIDs.csv"
ForEach ($line in $allobjects)
{
Get-MsolDevice -ObjectID $line.ObjectId | Select DisplayName,DeviceTrustType,RegisteredOwners,ApproximateLastLogonTimestamp| Export-Csv -Path "C:\temp\Project\IntuneDevices\Final.csv" -Append -NoTypeInformation
}
The problem is that when I open Final.csv the entry for RegisteredOwners shows up as System.Collections.Generic.List`1[System.String]
When I simply run the command from the terminal without exporting to a CSV so the oputput is displayed on the screen it looks fine, I see the RegisteredOwner listed in curly brackets like {username#domain.org}.
I've read that is because the output for RegisteredOwners is a list item and not simple text like the rest of the output, but I'm having a heck of time converting it inline.
I've tried things like inserting
Select -Property DisplayName,#{ n='RegisteredOwners'; e={ $_.RegisteredOwners -join ';' } }
But that errors during the run no matter the variations I've tried with it.
Any help with this would be greatly appreciated as I've searched and tried multiple solutions but none are working for me.
TIA
Thanks for pushing me in the right direction Bender, turns out I must have had some sort of syntax error I didn't understand. Here is the final code and it's working as intended.
## Script to collect all AzureAD registered devices, their trust type, and their owner.
## Connect to AzureAD and MSOL
Connect-MsolService
Connect-AzureAD
## Get all devices filtering their ObjectID
Get-AzureADDevice -All $True | Select ObjectID | Export-Csv "C:\temp\Project\IntuneDevices\AllAADObjectIDs.csv" -noType
## Create the variable from the expoted Csv
$allobjects = Import-Csv "C:\temp\Project\IntuneDevices\AllAADObjectIDs.csv"
## Create a new file using Column 1 of allobjects.csv entries to suss the information required for each device
ForEach ($line in $allobjects)
{
Get-MsolDevice -ObjectID $line.ObjectId | Select DisplayName,DeviceTrustType,#{ n='RegisteredOwners'; e={ $_.RegisteredOwners -join ';' } },ApproximateLastLogonTimestamp | Export-Csv -Path "C:\temp\Project\IntuneDevices\Final.csv" -Append -NoTypeInformation
}