1

У меня есть два похожих сценария PowerShell для резервного копирования файлов (сначала очищает сетевой диск, второй делает реальную резервную копию), настроенный для ежедневной работы в одной задаче планировщика Windows (только разные действия):Запланированный скрипт не перенаправляет вывод в файл

Action: Start a program 
Program/script: powershell.exe 
Add arguments (optional): -command C:\Webs\Scripts\purgar-backups-dinahosting.ps1 > C:\Webs\Scripts\purgar-backups-dinahosting.log 2>&1 

Action: Start a program 
Program/script: powershell.exe 
Add arguments (optional): -command C:\Webs\Scripts\backup-dynahosting.ps1 > C:\Webs\Scripts\backup-dynahosting.log 2>&1 

Я получаю ожидаемые файлы журнала, но первый всегда пуст (0 байт). Я получить фактический выход, если я просто запустить команду из командной строки:

powershell.exe -command C:\Webs\Scripts\purgar-backups-dinahosting.ps1 > C:\Webs\Scripts\purgar-backups-dinahosting.log 2>&1 

... с той лишь особенностью, что она использует Unix линии питает (: -!). Учитывая, что:

  1. Оба сценария сохраняются в строке Windows, каналы
  2. Оба сценария генерируют выходной сигнал с Write-Host

Что может объяснить эти странности в первом сценарии ?

() Вот код:

$LetraUnidad = "X:" 

$RecursoNFS = "xxx_removed_xxx.dinaserver.com:/usr/containers/xxx_removed_xxx" 

$EspacioContratado = "xxx_removed_xxx" 

$LimitePorcentaje = "xxx_removed_xxx" 



Write-Host "Verificando si ya está montada la unidad de red en $LetraUnidad..." 
$UnidadRed = New-Object System.IO.DriveInfo($LetraUnidad) 
if ($UnidadRed.IsReady) 
{ 
    Write-Host "Unidad de red disponible" 
} 
else 
{ 
    Write-Host "Unidad de red no disponible, montando unidad..." 
    net use $LetraUnidad $RecursoNFS 

    if ($UnidadRed.IsReady) 
    { 
     Write-Host "Unidad de red disponible" 
    } 
    else 
    { 
     Write-Host "Se ha producido un error al intentar montar la unidad de red" 
     exit 
    }  
} 



Write-Host "Obteniendo datos de espacio de la unidad $LetraUnidad..." 

$EspacioOcupado = ((Get-ChildItem $LetraUnidad -Recurse | Measure-Object -property length -sum).sum) /1gb 
$EspacioLibre = $EspacioContratado-$EspacioOcupado 
$PorcentajeEspacioOcupado = ($EspacioOcupado*100/$EspacioContratado) 


Write-Host "Espacio total:  " ([System.Math]::Round($EspacioContratado, 2)) " GB" 
Write-Host "Espacio libre:  " ([System.Math]::Round($EspacioLibre, 2)) " GB" 
Write-Host "Espacio ocupado:  " ([System.Math]::Round($EspacioOcupado, 2)) " GB" 
Write-Host "Porcentaje ocupación: " ([System.Math]::Round($PorcentajeEspacioOcupado, 2))"%" 
Write-Host 

Write-Host "Comprobando si es necesario eliminar archivos..." 
if($PorcentajeEspacioOcupado -gt $LimitePorcentaje) 
{ 
    Write-Host "Poco espacio disponible, eliminando archivos..." 
} 
else 
{ 
    Write-Host "Espacio disponible suficiente, no es necesario eliminar archivos" 
    exit 
} 



foreach ($file in Get-ChildItem -path X: | where-object{-not $_.PSIsContainer} | sort -property LastWriteTime) 
{ 
    Write-Host "Eliminando " $file.FullName 
    del $file.FullName 

    $EspacioOcupado = ((Get-ChildItem $LetraUnidad -Recurse | Measure-Object -property length -sum).sum) /1gb 
    $EspacioLibre = $EspacioContratado-$EspacioOcupado 
    $PorcentajeEspacioOcupado = ($EspacioOcupado*100/$EspacioContratado) 

    if($PorcentajeEspacioOcupado -lt $LimitePorcentaje) 
    { 
     Write-Host 
     exit 
    } 
} 
+1

CMD интерпретируют '>' и '2> & 1 'как операторы перенаправления и обрабатывать их самостоятельно и не передавать их в PowerShell. Планировщик задач интерпретирует аргументы как литерал. Таким образом, '>' и '2> & 1' будут переданы в PowerShell и будут обработаны PowerShell. И PowerShell знает, что поток хоста не должен перенаправляться оператором '>'. – PetSerAl

+0

@PetSerAl Спасибо за головы. Я никогда не понимал, почему или когда мне нужно разделить свои действия в трех (крошечных) текстовых полях; эти настройки были фактически результатом некоторой охоты на мусорщиков Google. Какой был бы правильный способ запустить * .ps1 и отправить его вывод в файл? –

+1

Одним из способов, который не требует изменения скриптов, будет: * program: * 'cmd' и * arguments: *'/c powershell -command C: \ Webs \ Scripts \ backup-dynahosting.ps1> C: \ Webs \ Scripts \ backup-dynahosting.log 2> & 1'. – PetSerAl

ответ

1
Write-Host 

может не правильный инструмент для работы. Поскольку он предназначен для прямой записи вывода в консоль пользователя (хост сценария) без фактического вывода вывода, например. перенаправлять или конвейер.

Это очень полезно при написании отчетов об ошибках, отчетах или ходе выполнения, которые вы не хотите видеть в журнале, но только в интерактивном сеансе. Или для сообщений от внутренних функций, которые не должны «вернуться», что сообщение

Попробуйте использовать

Write-Output 

для всего, что вы хотите, чтобы ваш скрипт для вывода. Будьте осторожны с внутренними функциями.

http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful/

+0

Вот и все! Не знаю, почему другой скрипт создал правильный файл журнала, но, честно говоря, мне все равно :) –

+0

'>' сообщает хосту сценария перенаправить вывод скрипта. он не является частью самого скрипта. я могу себе представить, что при запуске скрипта с разными хостами (powershell.exe vs the shedler) перенаправление выполняется по-другому. Но что бы это ни было, похоже, теперь это работает.Поражаю, что вы пометили мой ответ как подтвержденный :) – Darcon

+0

О, и, чтобы awnser вопрос в вашем комментарии выше: Попробуйте использовать 'Start-Transcript -Append -Path $ logFile'. – Darcon

 Смежные вопросы

  • Нет связанных вопросов^_^