Reputation: 11
With PowerShell I am trying to take information from a CSV file and execute two commands that are based on two columns of data. The first piece of data is an asset that needs to copy a unique file to a folder and have renamed to config.txt.
The second piece of data is a name for a computer to have the folder that had received the unique file copied to the named computer. For example;
First command:
Copy-Item "c:\folder1\$asset.txt" -Destination "f:\folder2\config.txt"
Second command:
robocopy /e folder2 \\$ComputerName\folder3
The data is imported from a csv file that has two columns, asset
and computername
. The script is at follows and is one of many variations, none of which has worked including the one below. Any help would be much appreciated.
Computers.csv
contains the following
A12345 CN12345
A54321 CN54321
Script:
Import-Csv -Delimiter ',' -Path c:\temp\computers.csv -Header 'Asset','ComputerName’ |
ForEach-Object {
$asset += $_.asset
$ComputerName += $_.NBN
Copy-Item "c:\folder1\$asset.txt" -Destination "f:\folder2\config.txt"
robocopy /e f:\folder2 \\$ComputerName\folder3
}
I have worked on the script and the results are below. The script does what I want except I manually have to change the position of the items in the array. I would like to have this done automatically but haven't figured that part out yet. I expect the csv file to contain 50 or more assets and computer names and don't look forward entering in the positions of each item and running the script 50 times. Is there a way to go through the array automatically?
$computers = Import-Csv -Path c:\temp\computers.csv -Header 'Asset','ComputerName' $asset = $computers[0].asset $ComputerName = $computers[0].ComputerName
ForEach-Object {
Copy-Item "c:\folder1\$asset.txt" -Destination "f:\folder2\config.txt"
robocopy /e /is "f:\folder2\" "\\$ComputerName\c$\folder3"
}
Upvotes: 1
Views: 127
Reputation: 974
First, make sure that your csv does not already contain headers. If it does, and you use the -header
flag then a duplicate header will be added to the contents.
I tested this solution using a csv, with no header, with these contents:
abc,123,
def,456,
ghi,789
Whenever I'm debugging code that involves accessing values in a loop, I like to write some code to write those values to the console like this:
$assetIndex = 0
Import-Csv -Header Asset,ComputerName -Path C:\noHeader.csv |
ForEach-Object {
Write-Host ([string]::Concat('Asset at index ',$assetIndex, ': The asset value is "', $_.Asset, '", The computer name is "', $_.ComputerName,'"'))
$assetIndex++
}
Running that will prove that we are correctly accessing values inside the loop.
Lastly, string concatenation can be a little confusing inside loops when accessing values with $_
.
Here are 2 examples of how you could build your copy-item
file path inside the loop:
#example 1
"c:\folder1\$($_.asset).txt"
#example 2
[string]::Concat('c:\folder1\',$_.Asset, '.txt')
Putting it all together we get:
Import-Csv -Header Asset,ComputerName -Path C:\noHeader.csv |
ForEach-Object {
Copy-Item "c:\folder1\$($_.asset).txt" -Destination "f:\folder2\config.txt"
robocopy /e /is "f:\folder2\" "\\$($_.ComputerName)\c$\folder3"
}
When placing variables inside of quotes, if you want to access the properties of that variable then you need to use the $($myVariable.someProperty)
syntax, otherwise the .someProperty
will just be interpreted as a string.
Upvotes: 1