我正在撰寫一個將目錄結構(不包括檔案)克隆到新目錄的腳本。到目前為止,這是我的代碼:
Function Copy-DirectoryStructure{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$Path
)
# Test whether the path is exactly a drive letter
if($Path -match '^[a-zA-Z]:\\$' -or $Path -match '^[a-zA-Z]:$'){
throw "Path cannot be at the root of a drive. Aborting."
}
# Check if the path is valid
if(Test-Path -Path $Path -PathType Container){
# Create the destination path format
$DestinationPath = (get-item $Path).FullName ' Folder Copy'
# Test if our destination already exists.
# If so, prompt for a new name
if(Test-Path -Path $DestinationPath -PathType Container){
Write-Warning "The destination path already exists."
$NewFolderName = Read-Host -Prompt "Input the name of the new folder to be created."
$DestinationPath = (get-item $Path).parent.FullName '\' $NewFolderName
}
# Begin copy
robocopy $Path $DestinationPath /e /xf *.* | Out-Null
} else {
throw "Invalid directory was passed. Aborting."
}
}
Copy-DirectoryStructure -Path "C:\Users\[username]\Desktop\Test"
相關部分在這里:
# Create the destination path format
$DestinationPath = (get-item $Path).FullName ' Folder Copy'
# Test if our destination already exists.
# If so, prompt for a new name
if(Test-Path -Path $DestinationPath -PathType Container){
Write-Warning "The destination path already exists."
$NewFolderName = Read-Host -Prompt "Input the name of the new folder to be created."
$DestinationPath = (get-item $Path).parent.FullName '\' $NewFolderName
}
現在,如果 $DestinationPath 已經存在,它會提示用戶輸入一個新名稱,然后繼續執行 robocopy。但是,如果用戶輸入的檔案夾名稱也已經評估為現有路徑,該怎么辦?
我想優雅地處理這種情況并重新提示輸入新路徑,直到用戶輸入尚不存在的目標路徑。
我不知道該怎么做。
我知道這是一個極端的極端情況,但我想讓我的代碼盡可能安全。
任何幫助是極大的贊賞。
uj5u.com熱心網友回復:
從函式中完全洗掉互動式位 - 它應該只是在目標路徑存在時失敗 - 而是為用戶提供一種顯式傳遞替代目標路徑的方法:
Function Copy-DirectoryStructure{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$Path,
[Parameter(Mandatory=$false)]
[string]$DestinationPath
)
$ErrorActionPreference = 'Stop'
# Test whether the path is exactly a drive letter
if($Path -match '^[a-zA-Z]:\\$' -or $Path -match '^[a-zA-Z]:$'){
throw "Path cannot be at the root of a drive. Aborting."
}
# Check if the path is valid
if(-not(Test-Path -Path $Path -PathType Container)){
throw "Path must describe an existing directory"
}
# Create the destination path format
if(-not $PSBoundParameters.ContainsKey('DestinationPath'))
{
$DestinationPath = (Get-Item $Path).FullName ' Folder Copy'
}
# Test that the destination isn't an existing file system item
if(Test-Path -Path $DestinationPath){
throw "The destination path already exists."
}
# If we've reached this point all validation checks passed, begin copy
robocopy $Path $DestinationPath /e /xf *.* | Out-Null
}
既然函式可以預見地失敗,我們可以使用錯誤處理來處理函式外部的重試邏輯:
while($true){
$path = Read-Host "Give a target path!"
try {
Copy-DirectoryStructure -Path $path
break
}
catch {
if($_ -match 'The destination path already exists.'){
$destPath = Read-Host "Wanna try an alternative destination path (input NO to start over)"
if($destPath -ceq 'NO'){
continue
}
Copy-DirectoryStructure -Path $path
break
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/327021.html
上一篇:將回傳值存盤到變數
