Powershell 如何在运行当前脚本之前更新它?

Powershell 如何在运行当前脚本之前更新它?,powershell,Powershell,我们在网络共享A上有一些PowerShell脚本,在只读网络共享B上有这些脚本的最新版本。只读共享是生成系统的输出,路径中有生成编号。部分是出于习惯,部分是因为脚本必须在磁盘上创建文件,但主要是因为路径是可预测的,所以我们在执行它们之前将PowerShell脚本复制到网络共享中。问题是,我们并不总是将脚本复制到网络共享,所以偶尔这些脚本会过时 我正在尝试创建一个脚本来更新网络共享a上的PowerShell脚本(通过从共享B复制最新版本),然后执行这些最新脚本。现在,我的想法是创建一个小脚本,从共

我们在网络共享A上有一些PowerShell脚本,在只读网络共享B上有这些脚本的最新版本。只读共享是生成系统的输出,路径中有生成编号。部分是出于习惯,部分是因为脚本必须在磁盘上创建文件,但主要是因为路径是可预测的,所以我们在执行它们之前将PowerShell脚本复制到网络共享中。问题是,我们并不总是将脚本复制到网络共享,所以偶尔这些脚本会过时

我正在尝试创建一个脚本来更新网络共享a上的PowerShell脚本(通过从共享B复制最新版本),然后执行这些最新脚本。现在,我的想法是创建一个小脚本,从共享B获取最新的脚本,复制到共享a,然后在共享a上执行该脚本


是否可以让脚本自身更新?也就是说,我是否可以让一个脚本(位于共享a上)将较新版本的自身从共享B复制到共享a,然后重新执行自身,而不是使用两个脚本?(我会加入一些关于文件创建日期的逻辑,以便在第一次执行时,它会自动更新,在第二次执行时,它会运行脚本的实际内容。)

是的,您可以更新正在运行的脚本,然后再次执行它。(请确保在更新后退出第一个脚本。)以下是我创建的一些示例代码:

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可能比我多。如果您使用
调用表达式
,请确保在包含空格的任何参数周围重新添加引号。)


有一个缺点:如果脚本的未来版本中删除了一个强制脚本参数,那么您需要使用不再是强制参数运行脚本至少一次,然后它会自动更新,从而允许您删除该参数。

下面是我编写的一个函数。将可能包含较新版本的文件的路径传递给它。这将更新自身,然后使用交给原始脚本的任何参数重新运行

  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

@aphoria我问这个问题是为了不去尝试,但是StackOverflow,唉,让我失望了。所以我必须学点东西。(太可怕了!)