Вызов exe-файла (7z) с помощью foreach в Powershell

#powershell #foreach #exe #7zip

#powershell #foreach #exe #7zip

Вопрос:

Я изо всех сил пытаюсь заставить powershell найти зашифрованные ZIP-файлы и извлечь из них 1 файл. Любая помощь будет оценена и заранее благодарна.

В Powershell это работает, когда путь жестко запрограммирован после ‘e’:

 $exe = 'C:Temp7z.exe'
$ZipPath = 'C:Temp'
amp; $exe -pPASSWORD -o"$ZipPath" e "$ZipPath23.02.2021.22.00.01.bak.zip" web.config -r
 

Однако я бы хотел, чтобы он нашел ZIP-файл, а затем извлек из него файл web.config. Я использую write-host для визуального вывода файла, чтобы я мог видеть, что это правильный файл, который он находит как:

Майкрософт.PowerShell.CoreFileSystem::C:Temp23.02.2021.22.00.01.bak.zip

но я получаю сообщение об ошибке:

ОШИБКА: система не может найти указанный файл.
Майкрософт.PowerShell.
ОШИБКА основной системы:
Система не может найти указанный файл.

Я пробовал следующее, но безуспешно:

 $exe = 'C:Temp7z.exe'
$ZipPath = 'C:Temp'
$ZipFile = Get-ChildItem $ZipPath *.zip -rec

foreach ($file in $ZipFile)
{
    Write-Host 'file:' $file.PSPath
    amp; $exe -pPASSWORD -o"$ZipPath" e $file.PSPath web.config -r
}
 

Я также пытался:

 $exe = 'C:Temp7z.exe'
$ZipPath = 'C:Temp'
$ZipFile = Get-ChildItem $ZipPath *.zip -rec

foreach ($file in $ZipFile)
{
    Write-Host 'file:' $file.PSPath
    amp; $exe -argumentList "-pPASSWORD", "-o$ZipPath", "e", "$file.PSPath", "web.config", "-r" -wait
}
 

Это полный результат запуска моего первого FOREACH без переключателя списка аргументов:

файл: Microsoft.PowerShell.CoreFileSystem::C:Temp23.02.2021.22.00.01.bak.zip

7-Zip 18.05 (x64): Авторское право (c) 1999-2018 Игорь Павлов: 2018-04-30

Сканирование диска на наличие архивов: 7z.exe : В строке:10 символ:5
amp; $exe -pPASSWORD -o$ZipPath e $файл.PSPath web.config -r
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : не указано: (:String) [], RemoteException
FullyQualifiedErrorId: ошибка NativeCommandError

ОШИБКА: система не может найти указанный файл.
Майкрософт.PowerShell.
ОШИБКА основной системы:
Система не может найти указанный файл.

Комментарии:

1. Взгляните на параметры здесь: PowerShell: запуск исполняемых файлов Что касается цикла, как насчет того, чтобы просто выполнить это: (Get-ChildItem -Path 'D:temp*.zip' -Recurse).FullName | ForEach{...} ?

Ответ №1:

Я решил минимальный пример — просто извлеките все zip-файлы в каталог с тем же именем, поскольку у меня нет zip-файлов, настроенных так, как у вас. Я надеюсь, что вы можете использовать формат того, что я создал, чтобы решить проблему встраивания параметров в ваш вопрос.

 Get-ChildItem *.zip | ForEach-Object {
    # no -argumentList, just pass the parameters like you'd enter them
    # (just with variables where you need them)
    amp; "C:Program Files7-Zip7z.exe" x $($_.FullName) -o*
}
 

Ответ №2:

ОШИБКА: система не может найти указанный файл.
Майкрософт.PowerShell.Core

Это говорит о том, что вы передаете PSPath свойство в качестве аргумента командной строки в 7-Zip. Вероятно, он видит:

 Microsoft.PowerShell.CoreFileSystem::C:Temp23.02.2021.22.00.01.bak.zip
 

Который не является допустимым путем за пределами PowerShell. Чтобы избежать этого в будущем, вы можете использовать FullName свойство [FileInfo] объектов, возвращаемых Get-ChildItem . Кроме того, -ArgumentList и -Wait являются параметрами Start-Process и не будут работать с оператором вызова amp; .

Поскольку вы ожидаете, что будет несколько архивов и, следовательно, несколько web.config файлов, лучшим подходом может быть использование переключателя include archive -ai в 7-Zip для поиска архивов в каталоге. Вы также хотели бы использовать -an для отключения поля archive_name и -aou для автоматического переименования каждого извлеченного файла web.config, поскольку вы используете команду extract e , которая извлекает все в один каталог.

 $exe = 'C:Temp7z.exe'
$ZipPath = 'C:Temp'
$InnerFilename = 'web.config'
$Password = 'PASSWORD'

$7zParams = @{
    FilePath = $exe
    ArgumentList = 'e -an -aou -r -p"{0}" -o"{1}" -air!"{2}" "{3}"' -f
        $Password, $ZipPath, "$ZipPath*.zip", $InnerFilename
    Wait = $true
}
Start-Process @7zParams
 

Краткое изложение 7-Zip-переключателей, используемых здесь по порядку, для всех, кто еще заинтересован:

Параметр Описание
e Извлечение файлов без структуры каталогов
-an Отключить обработку имя_архива
-aou Не перезаписывайте файлы с одинаковыми именами, автоматически переименовывайте извлеченные файлы
-r Рекурсивный поиск внутри каждого архива
-p"<password>" Используется <password> для расшифровки архивов
-o"<path>" Извлекать файлы в <path>
-air!"<path>*.zip" Рекурсивный поиск в <path> ZIP-архивах
<filename> Поиск совпадающих файлов <filename> в каждом архиве