Пакетное переименование файлов и папок в Windows Powershell

У меня есть сотни тысяч файлов, расположенных в ~40 папках (эти подпапки находятся в одной и той же суперпапке, которую я назову "test"). Я попытался использовать powershell для замены синтаксиса, найденного в имени папки, но также и в именах файлов.

В основном мои папки и файлы содержат ту же строку символов "PXXXX_0", которую я хочу переименовать в "PXXXX_".

Вот код, который я использовал, чтобы сначала сопоставить интересующие файлы и папки

cd C:\test

Get-ChildItem -Filter "*PXXXX_0*" -Recurse | Rename-Item -NewName {$_.name -replace 'PXXXX_0', 'PXXXX_'} -whatif

Это дает мне нужные файлы и предварительное действие (например,

What if: Performing operation "Rename File" on Target "Item: C:\test\PXXXX_053\PXXXX_053_558.jpg Destination C:\test\PXXXX_053\PXXXX_53_558.jpg

Так что, похоже, это работает, но только для файлов внутри папок, которые я также хочу переименовать.

Теперь, если я запускаю код без -whatif, оказывается, что переименовываются только имена папок, а не файлы...

Я почти уверен, что что-то пропустил, но так как я не очень знаком с этим языком, я изо всех сил пытаюсь найти решение. Я использую Powershell v1.0

Спасибо за любую помощь.

Лучший

1 ответ

Один лайнер:

 $items = get-childitem -filter "*PXXXX_0*" -Recurse; foreach ($item in $items) { $newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_'; rename-item $item.fullname -NewName $newName; }

Легко на глазных яблоках:

$items = get-childitem -filter "*PXXXX_0*" -Recurse;
foreach ($item in $items) { 
  $newName = $item.fullname -replace 'PXXXX_0', 'PXXXX_'; 
  rename-item $item.fullname -NewName $newName; 
}

Короче говоря, PowerShell 1 пытался переименовать файл, указав только имя файла, а не полный путь. По сути, он не смог найти ваши файлы, когда они были в подпапках.

Я проверил вашу логику в v5, и она работает так, как вы ожидаете.

Я собираюсь остановиться здесь и предположить, что вы пытаетесь запустить этот скрипт через System Center Orchestrator, так как вы работаете с PowerShell v1. Я чувствовал эту боль. Я рекомендую обернуть все ваши PS-скрипты в Runbooks в invoke-command -scriptblock {} -Credential $myCreds блоки. Это способствует выполнению в версии PowerShell целевой системы. Это также упрощает использование -ComputerName для запуска сценария на целевом сервере вместо сервера Runbook.

Затем вы можете сохранить пару имени пользователя и пароля в качестве переменных Orchestrator (используйте опцию шифрования) и вставить их в свое заявление get-credential выше. Сначала это кажется очень грязным, но вы привыкли к этому.

чтобы проверить это, я запустил PowerShell с -version 1. Вот мой $PSVersionTable:

Name                           Value
----                           -----
CLRVersion                     2.0.50727.8689
BuildVersion                   6.1.7600.16385
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

У него была та же проблема, но это не могло быть совпадением 1 к 1 с тем, что собирается запустить Orchestrator. Выведите вывод, если он не работает, и я сделаю все возможное.

Другие вопросы по тегам