2016-12-16 2 views
0

Я пытаюсь написать сценарий, который собирает список имен серверов, затем выполняет итерацию через каждое имя сервера и захватывает вторую в новейшую папку в каталоге , переименовывает его и копирует на другой сервер. У меня возникают проблемы с тем, чтобы это работало все в одной команде, и я не уверен, что это лучший способ разделить его и заставить его работать правильно. Я получаю ошибки при попытке разных вещей, основной - «rename-item: невозможно оценить параметр« NewName », потому что его аргумент указан как блок сценария, и нет ввода». Вот фрагмент кода, который вызывает эту ошибку:Powershell: Get-ChildItem - piping to Rename-Item and Copy-Item

$serverNames = Get-Content -Path "C:\servers.txt" 

foreach ($serverName in $ServerNames) { 

$reportServer = "a56741035" 

Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where { $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | Rename-Item -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" } 

Другой «не может связать аргумент параметра„Путь“, поскольку он является недействительным». Вот код, который вызывает эту ошибку:

$serverNames = Get-Content -Path "C:\servers.txt" 

foreach ($serverName in $ServerNames) { 

$reportServer = "a56741035" 

Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where { $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" } } 

Я чувствую, что я очень близко и просто ничего не вижу. Любая помощь очень ценится, большое вам спасибо. Хорошего дня.

отредактирован СОДЕРЖАТЬ КОД: НОВЫЕ

Get-ChildItem "\\$($serverName)\d$\mposlogs\device" | where { $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ("$serverName" + "_" + $_.Name) ; Copy-Item $_.FullName -Destination "\\$($reportServer)\c$\temp\mpos\logs" } 

ПРАВИЛ НОВЕЙШИХ КОММЕНТАРИИ:

Get-Child-Item "\\$serverName\d$\mposlogs\device" | where {$_.PSIsContainer} | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ("$serverName" + "" + $.Name) ; Copy-Item ("$serverName" + "" + $.Name) -Destination "\\$reportServer\c$\temp\mpos\logs" } 

ответ

1

Так это оказалось труднее, чем я думал, что это будет, трюк в том, что Rename-Item, кажется, в основном потребляет конвейерный объект, не давая вам возможность использовать этот объект в последующем имени (используя ScriptBlock также на самом деле не является идеальным, гораздо проще использовать простой concatted строки), поэтому вы должны изменить Rename-Item части вашего цикла слегка

Rename-Item -Path $_.FullName -NewName ("$serverName" + "_" + $_.Name) 

Что касается изменения синтаксиса prageeth ПРЕДЛАГАЕТ вы можете сделать их но они не нужны и увеличивают двусмысленность (Get-Childitem не требует escape-символа для доступа админ-ресурс, и нет ничего плохого в использовании синтаксиса $ ($) даже при отсутствии доступа к свойству).

EDIT

Ok после работы в комментариях для немного здесь является обновленной версией полного трубопровода GCI. Я успешно проверил его в своей среде, так что пальцы скрестили его. Пожалуйста, дайте мне знать, если какая-либо его часть не имеет смысла.

Get-ChildItem "\\$serverName\d$\mposlogs\device" | where {$_.PSIsContainer} | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName ("$serverName" + "_" + $_.Name) -PassThru | Copy-Item -Destination "\\$reportServer\c$\temp\mpos\logs" } 
+0

Я думаю, что это очень близко к прибиванию! Единственная часть, которую он не выполняет, - это копия файла. Это не ошибка ... он просто не копирует файл. :) Есть идеи? Спасибо! – LilithGoddess

+0

oh wow yea не видел, как там был установлен конвейер, проблема в том, что 'rename-item' не передает объект через' Copy-Item', вы можете преодолеть два способа: либо добавить ' -PassThru' переключится на ваш «Переименовать-элемент» или просто измените ваш '|' на ';', который затем обработает копию в качестве второй команды для выполнения в foreach, а не в элементе конвейера –

+0

ПОЛУЧИТЬ ТАК ЗАКРЫТЬ !! ! Теперь кажется, что он переименовывает файл, но затем пытается скопировать файл до его переименования? (не может найти путь xxxxx, потому что его не существует) - и когда я смотрю на папку, он был переименован правильно, но ошибка на самом деле вызывает папку до ее переименования ... это имеет смысл? – LilithGoddess

0

Edit:

Как уже упоминалось пользователь микрофон, кажется, что админ акции не нужно $ сбежать с. Реальной проблемой является командлет rename-Item, отсутствующий в параметре -Path. Спасибо, что принесли это Майку!

Однако я по-прежнему рекомендую удалить дополнительное $ over $ ($ serverName), чтобы уменьшить двусмысленность.

Попробуйте это!

Get-ChildItem "\\$serverName\d$\mposlogs\device" | where { $_.PSIsContainer } | Sort CreationTime -Descending | Select -Skip 1 | Select -First 1 | ForEach-Object { Rename-Item -Path $_.FullName -NewName { "$serverName" + "_" + $_.Name } | Copy-Item $_.FullName -Destination "\\$reportServer\c$\temp\mpos\logs" } } 
+0

Благодарим за отзыв. Я сделал предложенные изменения и переработал свой код, и он по-прежнему дает мне ту же ошибку: «Невозможно оценить параметр« NewName », потому что его аргумент указан как блок сценария, и нет ввода. Блок сценария нельзя оценить без ввода». – LilithGoddess

+0

ya '-Path' необходим, но вы также не можете использовать скриптовый блок для создания имени, не делая какой-то странный источник точек, который просто не нужен. и лично я думаю, что '$ ($ servername)' менее двусмысленно, чем '$ servername', но это не очень важно в этом контексте. –

0

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

# Rename doesn't output anything by default 
Rename-Item ToBeRenamed.txt Renamed.txt 

# For most commands with that default behaviour, you can use -PassThru to force output 
Rename-Item ToBeRenamed.txt Renamed.txt -PassThru 

# Once we have something in the pipeline, we can pipe result to Copy-Item 
Rename-Item ToBeRenamed.txt Renamed.txt -PassThru | Copy-Item -Destination C:\temp 
ls C:\temp\Renamed.txt 

Я бы рекомендовал избегать ForEach-Object здесь - это на самом деле не нужны.Вам просто нужно контролировать вывод команд, вот и все.