PowerShell网络驱动器映射类提示成功但未实际映射问题求助
PowerShell网络驱动器映射异常问题
问题说明
我编写了一个PowerShell类,用于自动映射网络驱动器并将凭据存储在XML文件中,避免每日重复输入密码。尝试使用New-PSDrive和net use两种方式实现映射时,脚本均提示操作成功,但实际并未完成驱动器映射。该类是包含XAML GUI和拖放事件处理的大型脚本的核心模块,驱动器映射失败会导致后续功能完全无法运行。
手动执行命令Net use z: \\server.blah.blah.org\c$ /user mydomain\myusername /persist:y mypassword可正常完成映射,但在PowerShell 5.1和pwsh 7.5版本中运行脚本时均出现上述问题。
相关代码
class NetworkDrive { [string]$DriveLetter [string]$SharePath [string]$Username [string]$Domain [string]$CredsFile NetworkDrive([string]$driveLetter, [string]$sharePath, [string]$username, [string]$domain){ $this.DriveLetter = $driveLetter $this.SharePath = $sharePath $this.Username = $username $this.Domain = $domain $this.CredsFile = "$env:USERPROFILE\drive-creds-$($driveLetter).xml" } [System.Management.Automation.PSCredential] GetCredential() { if (-Not (Test-Path $this.CredsFile)) { Write-Host "No saved credentials found for drive $($this.DriveLetter). Prompting for password..." -ForegroundColor Yellow $password = Read-Host "Enter password for $($this.Username)" -AsSecureString $password | Export-Clixml -Path $this.CredsFile } else { try { $password = Import-Clixml -Path $this.CredsFile } catch { Write-Host "⚠️ Error reading the saved credentials. Prompting for password..." -ForegroundColor Yellow $password = Read-Host "Enter password for $($this.Username)" -AsSecureString $password | Export-Clixml -Path $this.CredsFile } } return [System.Management.Automation.PSCredential]::new("$($this.Domain)\$($this.Username)", $password) } [void] MapDrive() { $credential = $this.GetCredential() try { # Remove existing drive if (Get-PSDrive -Name $this.DriveLetter -ErrorAction SilentlyContinue) { Remove-PSDrive -Name $this.DriveLetter -Force Write-Host "Removed existing drive $($this.DriveLetter)" } # Attempt to create new drive mapping New-PSDrive -Name $this.DriveLetter -PSProvider FileSystem -Root $this.SharePath -Credential $credential if (Get-PSDrive -Name $this.DriveLetter -ErrorAction SilentlyContinue) { Write-Host "✅ Drive $($this.DriveLetter): mapped to $($this.SharePath)." -ForegroundColor Green $global:LastMappedDrive = $this.DriveLetter # If DropPath exists, navigate to it if (Test-Path -PathType Container "$($this.DriveLetter):\$($this.DropPath)") { Set-Location "$($this.DriveLetter):\$($this.DropPath)" Write-Host "Navigated to $($this.DriveLetter):\$($this.DropPath)" } else { Write-Host "Drop path $($this.DriveLetter):\$($this.DropPath) does not exist." } } else { Write-Host "⚠️ Drive $($this.DriveLetter) appears not to have been mapped correctly." } } catch { if ($_.Exception.Message -like "*Logon failure*") { Write-Error "❌ Failed to map drive $($this.DriveLetter): Bad username or password." $this.ClearSavedCredential() Write-Host "Prompting for new credentials..." -ForegroundColor Yellow $credential = $this.GetCredential() try { New-PSDrive -Name $this.DriveLetter -PSProvider FileSystem -Root $this.SharePath -Credential $credential Write-Host "✅ Drive $($this.DriveLetter): mapped to $($this.SharePath)." -ForegroundColor Green $global:LastMappedDrive = $this.DriveLetter } catch { Write-Error "❌ Failed to map drive $($this.DriveLetter) again: $_" } } else { Write-Error "❌ Failed to map drive $($this.DriveLetter): $_" } } } [void] MapDriveNetUse() { $password = $this.GetCredential() # Ensure the network path is accessible before attempting to map if (-Not (Test-Path $this.SharePath)) { Write-Host "Error: Network path $($this.SharePath) is not accessible." -ForegroundColor Red return } try { # Remove existing drive $existingDrive = Get-PSDrive -Name $this.DriveLetter -ErrorAction SilentlyContinue if ($existingDrive) { net use "$($this.DriveLetter):" /delete /y if (Get-PSDrive -Name $this.DriveLetter -ErrorAction SilentlyContinue) { Write-Host "Error: Could not remove existing drive $($this.DriveLetter)." -ForegroundColor Red return } else { Write-Host "Removed existing drive $($this.DriveLetter)" } } # Attempt to create new drive mapping $cmd = "net use $($this.DriveLetter): \`"$($this.ServerPath)\`" /user:$($this.Domain)\$($this.Username) $password /persistent:yes" $result = Invoke-Expression $cmd start-sleep -Seconds 2 if ($LASTEXITCODE -ne 0) { throw "Failed to map network drive." } if (Get-PSDrive -Name $this.DriveLetter -ErrorAction SilentlyContinue) { Write-Host "✅ Drive $($this.DriveLetter): mapped to $($this.SharePath)." -ForegroundColor Green $global:LastMappedDrive = $this.DriveLetter # If DropPath exists, navigate to it # if (Test-Path -PathType Container "$($this.DriveLetter):\$($this.DropPath)") { # Set-Location "$($this.DriveLetter):\$($this.DropPath)" # Write-Host "Navigated to $($this.DriveLetter):\$($this.DropPath)" # } else { # Write-Host "Drop path $($this.DriveLetter):\$($this.DropPath) does not exist." # } } else { Write-Host "⚠️ Drive $($this.DriveLetter) appears not to have been mapped correctly." } } catch { if ($_.Exception.Message -like "*Logon failure*") { Write-Error "❌ Failed to map drive $($this.DriveLetter): Bad username or password." $this.ClearSavedCredential() Write-Host "Prompting for new credentials..." -ForegroundColor Yellow $credential = $this.GetCredential() try { $cmd = "net use $($this.DriveLetter): \`"$($this.ServerPath)\`" $password /user:$($this.Username) /persistent:yes" $result = Invoke-Expression $cmd if ($LASTEXITCODE -ne 0) { throw "Failed to map network drive." } Write-Host "✅ Drive $($this.DriveLetter): mapped to $($this.SharePath)." -ForegroundColor Green $global:LastMappedDrive = $this.DriveLetter } catch { Write-Error "❌ Failed to map drive $($this.DriveLetter) again: $_" } } else { Write-Error "❌ Failed to map drive $($this.DriveLetter): $_" } } } [void] ClearSavedCredential() { if (Test-Path $this.CredsFile) { Remove-Item $this.CredsFile -Force Write-Host "🧹 Removed saved credentials at $($this.CredsFile)" } else { Write-Host "⚠️ No saved credentials to remove for drive $($this.DriveLetter)." } } static [void] ListMappedDrives() { Get-PSDrive -PSProvider FileSystem | Where-Object { $_.DisplayRoot -like "\\*" } | Format-Table Name, Root } static [void] MapMultiple([NetworkDrive[]]$drives) { foreach ($drive in $drives) { $drive.MapDrive() } } static [void] ClearAllSavedCredentials() { Get-ChildItem "$env:USERPROFILE" -Filter "drive-creds-*.xml" | ForEach-Object { Remove-Item $_.FullName -Force Write-Host "🧹 Removed: $($_.Name)" } } }
内容的提问来源于stack exchange,提问作者Matt Williamson
相关产品推荐
相关产品推荐

