2013-08-02 3 views
3

У нас есть сценарии PowerShell, живущие на сетевом ресурсе A, и последние версии этих сценариев, живущих в сети общего доступа только для чтения B. Общий доступ только для чтения - это результат нашей системы сборки, и у нее есть номер сборки в дорожка. Отчасти из-за привычки, отчасти потому, что скрипты должны создавать файлы на диске, но в основном из-за того, что пути предсказуемы, мы копируем сценарии PowerShell в общий сетевой ресурс A перед их выполнением. Беда в том, что мы не всегда скопируйте сценарии в общий сетевой ресурс A, поэтому иногда эти скрипты устарели.Как обновить текущий скрипт перед его запуском?

Я пытаюсь создать сценарий, который будет обновлять сценарии PowerShell на сетевом ресурсе A (путем копирования последних версий из общего ресурса B), а затем выполнить эти последние сценарии. Прямо сейчас, моя идея состоит в том, чтобы иметь крошечный скрипт, который захватывает последний скрипт из общего ресурса B, копирует его для совместного использования A, а затем выполняет этот скрипт на share A.

Возможно ли иметь само обновление скрипта? I.e., вместо двух сценариев, могу ли я иметь один скрипт (который живет на share A), который копирует более новую версию из share B для совместного использования A, а затем перезапускает само выполнение? (Я бы ввел некоторую логику о дате создания файла, чтобы при первом выполнении он обновлялся, а при втором выполнении он запускал фактическое мясо скрипта.)

+0

Вы пробовали? – aphoria

+0

@aphoria Я задал вопрос, чтобы мне не пришлось его пробовать, но StackOverflow, увы, подвел меня. Поэтому мне нужно было кое-что узнать. (Как ужасно!) – PotatoEngineer

ответ

1

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

Write-Host "Starting script" 
if ($(Get-Item G:\selfUpdater2.ps1).CreationTimeUtc -gt $(Get-Item G:\selfUpdater.ps1).CreationTimeUtc) { 
    Copy-Item G:\selfUpdater2.ps1 G:\selfUpdater.ps1 
    $(Get-Item G:\selfUpdater.ps1).CreationTimeUtc = [DateTime]::UtcNow 
    &G:\selfUpdater.ps1 
    exit 
} 
Write-Host "Continuing original script; will not get here if we updated." 

Обратите внимание, что, если у вас есть параметры, чтобы пройти вокруг, вы должны передать их целевой сценарий , Поскольку у вашего обновленного сценария может быть больше или меньше параметров, чем у вашего текущего скрипта (некоторые ограничения, некоторые из которых не связаны текущим скриптом), вам нужно будет перебирать как $script:MyInvocation.BoundParameters, так и $script:MyInvocation.UnboundArguments, чтобы забрать их все и передать их.

(Лично у меня было больше удачи с произвольным параметром обходя с помощью Invoke-Expression ".\scriptName.ps1 $stringOfArguments" чем &.\scriptName.ps1 $arguments, но ваш пробег может изменяться - или вы можете узнать больше PowerShell, чем я Если вы используете Invoke-Expression, то обязательно. повторно добавить кавычки вокруг каких-либо параметров, которые имеют пробелы в них)

Там один недостаток:. Если обязательный параметр скрипта удаляется в будущей версии сценария, то вам необходимо запустить скрипт по крайней мере один раз параметр no-longer-обязательный перед его обновлением позволяет вам отбросить параметр.

1

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

function Update-Myself 
{ 
    [CmdletBinding()] 
    param 
    (
     [Parameter(Mandatory = $true, 
        Position = 0)] 
     [string]$SourcePath 
    ) 
    #check that the destination file exists 
    if (Test-Path $SourcePath) 
    { 
    #The path of THIS script 
    $CurrentScript = $MyInvocation.ScriptName 
     if (!($SourcePath -eq $CurrentScript)) 
     { 
      if ($(Get-Item $SourcePath).LastWriteTimeUtc -gt $(Get-Item $CurrentScript).LastWriteTimeUtc) 
      { 
       write-host "Updating..." 
       Copy-Item $SourcePath $CurrentScript 
       #If the script was updated, run it with orginal parameters 
       &$CurrentScript $script:args 
       exit 
      } 
     } 
    } 
    write-host "No update required" 
} 

Update-Myself \\path\to\newest\release\of\file.ps1 
Смежные вопросы