我们有一些PowerShell脚本存在于网络共享A上,这些脚本的最新版本位于只读网络共享B上。只读共享是我们构建系统的输出,它的内部版本号为路径。部分是出于习惯,部分原因是脚本必须在磁盘上创建文件,但主要是因为路径是可预测的,我们在执行它们之前将PowerShell脚本复制到网络共享A.麻烦的是我们总是将脚本复制到网络共享A,所以这些脚本偶尔会过时。
我正在尝试创建一个脚本,用于更新网络共享A上的PowerShell脚本(通过从共享B复制最新版本),然后执行这些最新脚本。现在,我的想法是创建一个小脚本,从共享B中获取最新脚本,将其复制到共享A,然后在共享A上执行该脚本。
是否可以自行更新脚本?即,我可以拥有一个脚本(位于共享A上)而不是拥有两个脚本,它可以将较新的版本本身从共享B复制到分享A,然后重启自己的执行? (我会提出一些关于文件创建日期的逻辑,以便在第一次执行时,它会自行更新,在第二次执行时,它将运行脚本的实际内容。)
答案 0 :(得分:3)
是的,您可以更新您正在运行的脚本,然后再次执行。(只需确保在更新后退出第一个脚本。)以下是一些示例代码我创建了:
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
,请务必在其中包含空格的任何参数周围重新添加引号。)
存在一个缺点:如果在脚本的未来版本中删除了必需的脚本参数,那么您需要至少运行一次脚本并使用不再强制执行在它自动更新之前的参数允许你删除参数。
答案 1 :(得分:3)
这是我放在一起的功能。将它传递给可能包含较新版本的文件的路径。这将更新自己,然后重新运行任何传递给他原始脚本的参数。
> mart <- biomaRt::useMart(biomart = "ENSEMBL_MART_ENSEMBL",
+ dataset = "hsapiens_gene_ensembl",
+ host = "www.ensembl.org")