Powershell - If 语句未按预期执行
Powershell - If Statement Doesn't Execute as Intended
我已经编写了一个 Powershell 脚本来压缩我的文件并将它们复制到 USB 驱动器并且它按预期工作。但是,我决定更新脚本并添加错误日志,以防万一,并将其存储到文本文件中。
我的代码:
[string]$zipPath="C:\Users\someuserz.exe"
[string]$drive="E:\"
[string]$securityBackup="Security"
[string]$tempSecurity="temp_security"
[string]$keepasscopy="keepass_copy"
[string]$setDate
[string]$userPath="C:\Users\someuser\"
[string]$errorReport
[string]$errorText="C:\Users\someuser\errorLog.txt"
$dateVar = Get-Date
function createErrorReport($writeError){
$writeError += " " + $dateVar.ToString()
if(Test-Path ($errorText)){
$writeError | Add-Content $errorText
}
else
{
$writeError | Set-Content $errorText
}
}
<#Checking to see if the E:\ Drive exists, if it doesn't exit the script, if it does proceed#>
if(Test-Path ($drive)){
Write-Output ($drive + " Drive Exists")
}
Else{
# Write-Output ($drive + " Drive Doesn't Exist")
# $errorReport= ($drive + " Drive Doesn't Exist")
# createErrorReport($errorReport)
exit
}
[string]$buildDay=($dateVar.day.ToString())
[string]$buildMonth=($dateVar.Month.ToString())
[string]$buildYear=($dateVar.Year.ToString())
[string]$buildHour=($dateVar.Hour.ToString())
[string]$buildMinute=($dateVar.Minute.ToString())
[string]$buildSecond=($dateVar.Second.ToString())
[int]$checkDay = 0
[int32]::TryParse($buildDay,[ref]$checkDay)
[int]$checkMonth = 0
[int32]::TryParse($buildMonth,[ref]$checkMonth)
<#Checking to see if the day/month is less than 10, so that a zero could be applied#>
if($checkNum -le 10){
($buildDay="0"+$buildDay)
}
if($checkMonth -le 10){
($buildMonth="0"+$buildMonth)
}
<#Creating the setDate variable which is used as the name. That way the script can be run without user interaction anytime
Using the current day, month, year hour, minute and second we construct a name to apply to our zip file. #>
$setDate = $buildDay + "-" + $buildMonth + "-" + $buildYear + "-" + $buildHour + $buildMinute + $buildSecond
<#Create a temporary security directory in the user's path to store the KeePass files#>
md ("C:\Users\someuser\" + $tempSecurity)
<#If statement to check to see if the above directory was created. If it evaluates to true proceed #>
if(Test-Path ($userPath + $tempSecurity)){
<#Copy all the items in the security folder to the temporary folder that was created#>
<#Recurse: Ensures all files and folders are copied, not just the top level folder #>
Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $tempSecurity) -Recurse
md ($userPath + $keepasscopy+"\"+$setDate)
<#Check to see if the above folder, KeePass\setDate has been created #>
if(Test-Path ($userPath + $keepasscopy+"\"+$setDate)){
<#Copy all the items in the Security folder where KeePass is stored to the newly created directory of KeePass\setDate#>
Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $keepasscopy+"\"+$setDate) -Recurse
<#Call the 7-zip .exe and create a zip archive of the KeePass folder in the KeePass\setDate Directory#>
$invokeCommand = ($zipPath + (" a -tzip") + (" "+$drive + $setDate + ".zip") + (" " + $userPath + $keepasscopy+"\"+$setDate))
<#Calls the command to be started#>
Invoke-Expression $invokeCommand
<#Provided that the zip file is created on the USB drive remove the KeePass copy and the temporary copy from the user directory#>
if(Test-Path ($drive + $setDate + ".zip")){
Remove-item ($userPath + $keepasscopy) -Recurse
Remove-Item ($userPath + $tempSecurity) -Recurse
} <#If the script is unable to create a copy on the USB drive, then tell the user that a backup copy exists on the current user directory#>
else{
Write-Output ("Unable to create backup of KeePass in " +$drive + " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
$errorReport= ("Unable to create backup of KeePass in " +$drive + " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
createErrorReport($errorReport)
exit
}
}
else
{
Write-Output ("Unable to create KeePass copy in " + $userPath)
$errorReport= ("Unable to create KeePass copy in " + $userPath)
createErrorReport($errorReport)
exit
}
}
else{
Write-Output ("Unable to create temporary folder in " +$userPath)
$errorReport= ("Unable to create temporary folder in " +$userPath)
createErrorReport($errorReport)
exit
}
问题:
我的问题是第一个 if 语句,它检查我要复制到的 USB 驱动器是否存在,现在即使该驱动器确实存在,它也会打印到屏幕上,但它不存在,就在它的正下方,它将打印它并照常继续,即使我注释掉 Write-Output $drive doesn't exist,出于某种原因它仍然将它打印到屏幕上。换句话说,它会打印驱动器不存在,即使它已插入并且 Windows Explorer 可以看到和访问它。即使它说驱动器不存在,并且在它下面说它存在,ELSE 语句的其余部分也不会执行,这意味着它不会创建日志报告。
您的第一个 if 语句存在范围问题。在函数内部,您具有范围的是变量 $errorText
,它在函数 外部 声明。
[string]<b>$errorText</b>="C:\Users\someuser\errorLog.txt"
function createErrorReport($writeError){
$writeError += " " + $dateVar.ToString()
if(Test-Path (<b>$errorText</b>)){
$writeError | Add-Content $errorText
}
else{
$writeError | Set-Content $errorText
}
}
您有几种方法可以解决这个问题。您选择哪一个归结为偏好和需要。
您可以像这样使用 $global
范围关键字 answer
更好的编码实践是在函数内部声明变量(尤其是当它没有在其他任何地方使用时)
function createErrorReport($writeError){
[string]$errorText="C:\Users\someuser\errorLog.txt"
if(Test-Path ($errorText)){
}
}
或者作为参数传递给函数
function createErrorReport($writeError, $errorText){
if(Test-Path ($errorText)){
}
}
createErrorReport "Some Error" "C:\Users\someuser\errorLog.txt"
我已经编写了一个 Powershell 脚本来压缩我的文件并将它们复制到 USB 驱动器并且它按预期工作。但是,我决定更新脚本并添加错误日志,以防万一,并将其存储到文本文件中。
我的代码:
[string]$zipPath="C:\Users\someuserz.exe"
[string]$drive="E:\"
[string]$securityBackup="Security"
[string]$tempSecurity="temp_security"
[string]$keepasscopy="keepass_copy"
[string]$setDate
[string]$userPath="C:\Users\someuser\"
[string]$errorReport
[string]$errorText="C:\Users\someuser\errorLog.txt"
$dateVar = Get-Date
function createErrorReport($writeError){
$writeError += " " + $dateVar.ToString()
if(Test-Path ($errorText)){
$writeError | Add-Content $errorText
}
else
{
$writeError | Set-Content $errorText
}
}
<#Checking to see if the E:\ Drive exists, if it doesn't exit the script, if it does proceed#>
if(Test-Path ($drive)){
Write-Output ($drive + " Drive Exists")
}
Else{
# Write-Output ($drive + " Drive Doesn't Exist")
# $errorReport= ($drive + " Drive Doesn't Exist")
# createErrorReport($errorReport)
exit
}
[string]$buildDay=($dateVar.day.ToString())
[string]$buildMonth=($dateVar.Month.ToString())
[string]$buildYear=($dateVar.Year.ToString())
[string]$buildHour=($dateVar.Hour.ToString())
[string]$buildMinute=($dateVar.Minute.ToString())
[string]$buildSecond=($dateVar.Second.ToString())
[int]$checkDay = 0
[int32]::TryParse($buildDay,[ref]$checkDay)
[int]$checkMonth = 0
[int32]::TryParse($buildMonth,[ref]$checkMonth)
<#Checking to see if the day/month is less than 10, so that a zero could be applied#>
if($checkNum -le 10){
($buildDay="0"+$buildDay)
}
if($checkMonth -le 10){
($buildMonth="0"+$buildMonth)
}
<#Creating the setDate variable which is used as the name. That way the script can be run without user interaction anytime
Using the current day, month, year hour, minute and second we construct a name to apply to our zip file. #>
$setDate = $buildDay + "-" + $buildMonth + "-" + $buildYear + "-" + $buildHour + $buildMinute + $buildSecond
<#Create a temporary security directory in the user's path to store the KeePass files#>
md ("C:\Users\someuser\" + $tempSecurity)
<#If statement to check to see if the above directory was created. If it evaluates to true proceed #>
if(Test-Path ($userPath + $tempSecurity)){
<#Copy all the items in the security folder to the temporary folder that was created#>
<#Recurse: Ensures all files and folders are copied, not just the top level folder #>
Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $tempSecurity) -Recurse
md ($userPath + $keepasscopy+"\"+$setDate)
<#Check to see if the above folder, KeePass\setDate has been created #>
if(Test-Path ($userPath + $keepasscopy+"\"+$setDate)){
<#Copy all the items in the Security folder where KeePass is stored to the newly created directory of KeePass\setDate#>
Copy-Item ($userPath + $securityBackup+"\*") ($userPath + $keepasscopy+"\"+$setDate) -Recurse
<#Call the 7-zip .exe and create a zip archive of the KeePass folder in the KeePass\setDate Directory#>
$invokeCommand = ($zipPath + (" a -tzip") + (" "+$drive + $setDate + ".zip") + (" " + $userPath + $keepasscopy+"\"+$setDate))
<#Calls the command to be started#>
Invoke-Expression $invokeCommand
<#Provided that the zip file is created on the USB drive remove the KeePass copy and the temporary copy from the user directory#>
if(Test-Path ($drive + $setDate + ".zip")){
Remove-item ($userPath + $keepasscopy) -Recurse
Remove-Item ($userPath + $tempSecurity) -Recurse
} <#If the script is unable to create a copy on the USB drive, then tell the user that a backup copy exists on the current user directory#>
else{
Write-Output ("Unable to create backup of KeePass in " +$drive + " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
$errorReport= ("Unable to create backup of KeePass in " +$drive + " A backup copy exist " + $userPath + $keepasscopy+"\"+$setDate)
createErrorReport($errorReport)
exit
}
}
else
{
Write-Output ("Unable to create KeePass copy in " + $userPath)
$errorReport= ("Unable to create KeePass copy in " + $userPath)
createErrorReport($errorReport)
exit
}
}
else{
Write-Output ("Unable to create temporary folder in " +$userPath)
$errorReport= ("Unable to create temporary folder in " +$userPath)
createErrorReport($errorReport)
exit
}
问题:
我的问题是第一个 if 语句,它检查我要复制到的 USB 驱动器是否存在,现在即使该驱动器确实存在,它也会打印到屏幕上,但它不存在,就在它的正下方,它将打印它并照常继续,即使我注释掉 Write-Output $drive doesn't exist,出于某种原因它仍然将它打印到屏幕上。换句话说,它会打印驱动器不存在,即使它已插入并且 Windows Explorer 可以看到和访问它。即使它说驱动器不存在,并且在它下面说它存在,ELSE 语句的其余部分也不会执行,这意味着它不会创建日志报告。
您的第一个 if 语句存在范围问题。在函数内部,您具有范围的是变量 $errorText
,它在函数 外部 声明。
[string]<b>$errorText</b>="C:\Users\someuser\errorLog.txt"
function createErrorReport($writeError){
$writeError += " " + $dateVar.ToString()
if(Test-Path (<b>$errorText</b>)){
$writeError | Add-Content $errorText
}
else{
$writeError | Set-Content $errorText
}
}
您有几种方法可以解决这个问题。您选择哪一个归结为偏好和需要。
您可以像这样使用 $global
范围关键字 answer
更好的编码实践是在函数内部声明变量(尤其是当它没有在其他任何地方使用时)
function createErrorReport($writeError){
[string]$errorText="C:\Users\someuser\errorLog.txt"
if(Test-Path ($errorText)){
}
}
或者作为参数传递给函数
function createErrorReport($writeError, $errorText){
if(Test-Path ($errorText)){
}
}
createErrorReport "Some Error" "C:\Users\someuser\errorLog.txt"