Powershell 如果测试路径等于false,则执行应用程序安装

Powershell 如果测试路径等于false,则执行应用程序安装,powershell,Powershell,我正在编写一个脚本来测试目标目录中是否存在文件,如果为false,则执行应用程序安装 目标是测试文件是否存在,如果存在,则中止并记录原因。如果文件不存在,则应执行应用程序安装程序 我首先尝试使用newitem创建一个虚拟文件来创建目录和虚拟文件 New-Item -ItemType Directory -Force -Path "C:\temp" New-Item -Path "C:\temp\vistaupdated.txt" -ItemType "file" -Value "Updated"

我正在编写一个脚本来测试目标目录中是否存在文件,如果为false,则执行应用程序安装

目标是测试文件是否存在,如果存在,则中止并记录原因。如果文件不存在,则应执行应用程序安装程序

我首先尝试使用newitem创建一个虚拟文件来创建目录和虚拟文件

New-Item -ItemType Directory -Force -Path "C:\temp"
New-Item -Path "C:\temp\vistaupdated.txt" -ItemType "file" -Value "Updated"

# Test if computer is updated
$file = Get-Content "C:\temp\vistaupdated.txt"
$containsWord = $file | %{$_ -match "Updated"}
if ($containsWord -contains $false) { ###start running the install stuff
但是,如果文件不存在且未找到对象,则会出现此错误。然后,我决定切换策略并使用
测试路径

$file = Test-Path -Path "C:\temp\vistaupdated.txt"
if ($file -eq $false) { ###start running the install stuff
在这种情况下,我相信
$file
的计算结果将为False,从而执行安装。执行时,我得到的只是脚本路径的返回:

PS C:\users\me\desktop> $filetest = Test-Path -Path "C:\temp\vistaupdated.txt" PS C:\users\me\desktop> $filetest False PS C:\users\me\desktop> C:\Users\me\Desktop\vistaupdate.ps1 如果
测试路径
为False,则安装程序应在第一条If语句中启动。相反,脚本会返回脚本本身的路径并退出。

正如您在问题的注释中已经指出的,您从未调用函数
Vista Install
,因此您的代码实际上没有做任何事情也就不足为奇了。而且您不应该在嵌套范围中定义函数(或
$Vista*
$LogFile
变量)。
else
分支中的代码将无法找到您当前拥有的
Get TimeStamp
$LogFile

请允许我提出一些改进建议:

  • 您的日志代码有很多冗余信息。与其定义一个只用于生成时间戳的函数,不如创建一个将日志消息作为参数并以其他方式完全封装日志的函数

  • $cmdLine=“$VISTANSPATH$VISTANSEXE”
    将在没有路径分隔符的情况下组合目录路径和文件名,从而导致路径不正确。在变量之间加一个反斜杠:

    $cmdLine = "$VistaInsPath\$VistaInsEXE
    
    或者(更好)使用
    Join-Path
    cmdlet,建议如下:

    $cmdLine = Join-Path $VistaInsPath $VistaInsEXE
    
  • 测试路径直接置于
    if
    条件下。不需要先将结果赋给变量

  • 变量
    $errFlag
    是无意义的。只需将log语句放在
    启动进程之后即可。如果抛出异常,代码将转到
    catch
    块而不到达该语句

  • 我假设您只希望在安装没有抛出错误的情况下创建文件
    vistaupdated.txt
    ,这样代码也应该进入
    try

  • 新建项
    为该项输出一个对象。您可能希望抑制这种情况

  • Vista安装功能
    Vista Install
    也没有多大意义,因为它只会安装一个特定的程序。因为它一开始只有很少的代码,所以我将直接删除它并将代码放在“then”分支中。但是,如果您希望它成为一个函数,您应该正确地命名和参数化它:将程序和参数作为参数传递(最好以
    启动进程的参数命名,这样您就可以简单地命名变量),并使用符合以下条件的名称:

简化代码:

$VistaInsPath  = '\\apps\shared\me\vista\6.16.0'
$VistaInsEXE   =  'VistaClient.6.16.0.896'
$VistaInsParam = '/s', '/v', '/qn'

$logFile = '\\apps\shared\me\vista\6.16.0\log\vista_install.log'

function Write-Log {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [string]$Message = ''
    )

    "[{0:MM/dd/yy HH:mm:ss}]`t[{1}\{2}]`t{3}" -f (Get-Date), $env:COMPUTERNAME, $env:USERNAME, $Message |
        Out-File $script:LogFile -Append
}

if (-not (Test-Path -Path 'C:\temp\vistaupdated.txt')) {
    $cmdLine = Join-Path $VistaInsPath $VistaInsEXE
    try {
        Start-Process -FilePath $cmdLine -ArgumentList $VistaInsParam -Wait
        New-Item -Path 'C:\temp' -Type Directory -Force | Out-Null
        New-Item -Path 'C:\temp\vistaupdated.txt' -Type File -Value 'Updated' | Out-Null
        Write-Log 'Completed successfully.'
    } catch {
        Write-Log ('Error has occurred: {0}' -f $_.Exception.Message)
    }
} else {
    Write-Log 'Computer already updated. Aborting.'
}
可以为翻转“then”和“else”分支提供参数,以避免出现否定条件:

if (Test-Path -Path 'C:\temp\vistaupdated.txt') {
    Write-Log 'Computer already updated. Aborting.'
} else {
    $cmdLine = ...
    ...
}
或者,如果文件存在,则直接退出脚本,以完全避免
else
分支:

if (Test-Path -Path 'C:\temp\vistaupdated.txt') {
    Write-Log 'Computer already updated. Aborting.'
    exit
}

$cmdLine = ...
...

请参见
Get Help Test Path
,或者返回一个布尔值,您可以在if或where对象中检查它是否不是文件位置。顺便说一句,请阅读a是什么。代码从不调用
Vista安装
功能。你在期待什么?我还没有全部读过,但我可以告诉你的
$cmdLine
构造是错误的。现在,它将返回
“\\apps\shared\me\vista\6.16.0VistaClient.6.16.0.896”
。改用
连接路径-Path$VistaInsPath-ChildPath$vistainsex
if (Test-Path -Path 'C:\temp\vistaupdated.txt') {
    Write-Log 'Computer already updated. Aborting.'
} else {
    $cmdLine = ...
    ...
}
if (Test-Path -Path 'C:\temp\vistaupdated.txt') {
    Write-Log 'Computer already updated. Aborting.'
    exit
}

$cmdLine = ...
...