为何PowerShell脚本执行的是已修改文件的旧版本?
Azure Run Command 执行修改后PowerShell脚本仍读取旧版本的原因及解决方案
核心原因
- Azure Run Command 内置缓存机制:为优化执行效率,Azure 会将传入的脚本在VM侧的临时缓存目录留存备份,若多次执行的脚本名称一致,平台会优先调用缓存中的旧版本文件,而非重新读取磁盘上修改后的新文件。
- 文件IO异步延迟:
Set-Content属于PowerShell的非强制同步IO操作,执行完命令后,内容可能还保留在系统IO缓存中未刷入磁盘,同一进程内调用Get-Content会读取进程内缓存的新内容,但其他进程(包括Run Command的执行进程)读取磁盘时拿到的仍是旧版本。 - 路径上下文不匹配:Azure Run Command的默认执行工作目录为
C:\Windows\System32,如果传入的脚本路径为相对路径,会优先读取System32目录下的同名文件,若你修改的是其他目录下的同名称脚本,就会出现执行文件和修改文件不一致的问题。 - 权限访问限制:若修改后的脚本所在目录权限配置特殊,Run Command默认使用的本地系统账户无权限读取新修改的文件,平台会自动回滚调用之前可正常读取的缓存版本。
解决方法
- 规避缓存策略:每次修改脚本后,给脚本文件添加唯一标识后缀(如时间戳),示例命令:
$newScriptName = "template_$(Get-Date -Format 'yyyyMMddHHmmss').ps1",确保每次执行的脚本名称唯一,不会命中旧缓存。 - 强制同步写入:替换
Set-Content为.NET的同步写入方法,确保写入完成后再释放文件句柄,示例代码:[System.IO.File]::WriteAllText($scriptAbsolutePath, $modifiedContent, [System.Text.Encoding]::UTF8),写入完成后可添加2秒延迟确保磁盘刷入:Start-Sleep -Seconds 2。 - 统一使用绝对路径:修改文件和传入Run Command执行时,都使用完整绝对路径,避免相对路径的上下文差异。
- 校验文件一致性:修改完成后计算文件哈希:
Get-FileHash $scriptAbsolutePath | Select-Object -ExpandProperty Hash,同时在脚本开头添加哈希计算打印逻辑,对比两端哈希即可确认执行的是否为修改后的文件。
内容的提问来源于stack exchange,提问作者AdyM
相关产品推荐
相关产品推荐

