2

I have a csv file with two columns "Path" and "Owner".

I've created the below script and it can read from the CSV file, but when I attempt to assign the variables from the csv it fails.

Import-Csv C:\test\output.csv | ForEach-Object {
    $Path = $_.path
    $owner = $_.owner
    "The username is $Path and the owner is $owner"
}
ForEach-Object {
    $Path = $_.path
    $owner = $_.owner

    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList '$owner'
    $Acl = Get-Acl -Path $Path
    $Acl.SetOwner($Account)

    Set-Acl -Path $owner -AclObject $Acl
}

The output is correct from the first segment and shows the path and the owner, but the second part doesn't set the owner according to the path.

Norrin Rad
  • 353
  • 1
  • 5
  • 14

2 Answers2

3

The second foreach has no input object to iterate over. So either

  • import to a variable and pipe it twice to the foreach loops
  • import twice

$csv = import-csv c:\test\output.csv 
$csv | foreach-object {
  $Path = $_.path
  $owner =$_.owner
  "The username is $Path and the owner is $owner"
}
$csv | ForEach-Object {
    $Path = $_.path
    $owner =$_.owner
    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList "$owner"
    $Acl = Get-Acl -Path $path
    $Acl.SetOwner($Account);
    Set-Acl -Path $Path -AclObject $Acl
}
LotPings
  • 1,015
  • 7
  • 12
  • The issue now is it's not accepting the variables in $Acl.SetOwner($Account) Exception calling "SetOwner" with "1" argument(s): "Some or all identity references could not be translated." – Norrin Rad Mar 19 '17 at 15:24
  • Variables inside single quotes are not expanded, use double quotes instead (sorry didn't test this for the obvious previous mistake). – LotPings Mar 19 '17 at 15:27
  • Hi Thanks for your help with this.. I can't believe I made such schoolboy errors :) – Norrin Rad Mar 19 '17 at 15:31
  • the errors I am now getting is Set-Acl -Path $owner -AclObject $Acl; Set-Acl : Cannot find path and the way I have the csv set up is Path Owner C:\Users\Gin\Desktop\test\New folder Host\Nath C:\Users\Gin\Desktop\test\New folder - Copy Host\Raj – Norrin Rad Mar 19 '17 at 15:32
  • $owner is not a path, change to $path. Maybe you should use `Test-Path` prior trying to change the ownership. I'd gracefully accept a vote up and/or a checked answer. – LotPings Mar 19 '17 at 15:50
  • Excellent, thanks you so much for your help, saved me hours and spared the internet from a bashing :) – Norrin Rad Mar 19 '17 at 15:52
1
  1. When you use ForEach-Object, you need to return the current object for it to go through the pipe and into the next foreach. You can use return for this, or just type the current object variable ($_) at the end.

  2. Since you are passing $owner, you don't need to enclose it with quotations. Just use the variable.

  3. Don't use single quotations for variables because single quotations output the string with literal text you typed. So it's literally $owner and not value of $owner variable.

Code:

Import-Csv C:\test\output.csv | ForEach-Object {
    $Path = $_.path
    $owner = $_.owner
    "The username is $Path and the owner is $owner"
    return $_ # Returning current object
}
ForEach-Object {
    $Path = $_.path
    $owner = $_.owner

    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $owner # No quotations
    $Acl = Get-Acl -Path $Path
    $Acl.SetOwner($Account)

    Set-Acl -Path $owner -AclObject $Acl
}

Also, you don't need 2 foreach loops. Why not just join them? You can use Write-Host to output the string you wanted.

Import-Csv C:\test\output.csv | ForEach-Object {
    $Path = $_.path
    $owner = $_.owner
    Write-Host "The username is $Path and the owner is $owner"

    $Account = New-Object -TypeName System.Security.Principal.NTAccount -ArgumentList $owner
    $Acl = Get-Acl -Path $Path
    $Acl.SetOwner($Account)

    Set-Acl -Path $owner -AclObject $Acl
}