Назад | Перейти на главную страницу

Powershell читает из переменных набора CSV

У меня есть файл CSV с двумя столбцами «Путь» и «Владелец».

Я создал приведенный ниже сценарий, и он может читать из файла CSV, но когда я пытаюсь назначить переменные из CSV, он терпит неудачу.

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
}

Вывод правильный из первого сегмента и показывает путь и владельца, но вторая часть не устанавливает владельца в соответствии с путем.

Второй foreach не имеет входного объекта для перебора. Так что либо

  • импортировать в переменную и дважды передать ее в циклы foreach
  • импортировать дважды

$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
}
  1. Когда вы используете ForEach-Object, вам нужно вернуть текущий объект, чтобы он прошел через конвейер и в следующий цикл foreach. Ты можешь использовать return для этого или просто введите текущую объектную переменную ($_) в конце.

  2. Поскольку вы проходите $owner, цитаты заключать не нужно. Просто используйте переменную.

  3. Не используйте одинарные кавычки для переменных, потому что одиночные кавычки выводят строку с буквальным текстом, который вы набрали. Так что это буквально $owner а не ценность $owner переменная.

Код:

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
}

Кроме того, вам не нужно 2 петли по каждому элементу. Почему бы просто не присоединиться к ним? Ты можешь использовать Write-Host чтобы вывести нужную строку.

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
}