PowerShell扫描文件夹脚本异常:正确密码的Scanner用户仍创建Scanner2
PowerShell脚本用户验证逻辑错误修复
问题描述
编写的扫描到文件夹自动化配置脚本,预期逻辑为:
- 若本地存在
Scanner用户且密码为Example123,直接使用该用户 - 若
Scanner用户存在但密码不符,创建Scanner2用户 - 若
Scanner用户不存在,创建Scanner用户
但实际运行时,即便Scanner用户存在且密码正确,脚本仍会创建Scanner2。
问题根源
脚本中使用net user Scanner | Select-String -SimpleMatch "Example123"验证密码,net user命令不会输出用户的明文密码,所以这个判断永远返回$false,导致第一个条件无法触发,直接进入“密码不符”的分支创建Scanner2。
修复方案
使用System.DirectoryServices.AccountManagement命名空间中的类验证用户凭证,这是Windows环境下验证本地用户密码的可靠方法。
修复后的完整脚本
Write-Host @" ____ ____ ____ ____ _____ _ _ ' //////////////////////////////////////////////////////////////////////////// ' // // ' // ____ ____ ____ ____ _____ _ _ // ' // | _ \| _ \/ ___| ___ __ _ _ __ |___ \| ___|__ | | __| | ___ _ __ // ' // | | | | | | \___ \ / __/ _` | '_ \ __) | |_ / _ \| |/ _` |/ _ \ '__| // ' // | |_| | |_| |___) | (_| (_| | | | |/ __/| _| (_) | | (_| | __/ | // ' // |____/|____/|____/ \___\__,_|_| |_|_____|_| \___/|_|\__,_|\___|_| // ' // // ' //////////////////////////////////////////////////////////////////////////// "@ Set-ExecutionPolicy Bypass -Force $userName = Read-Host "通讯录显示名称: " Write-Host "以下是可用打印机及其IP地址" $printers = Get-Printer $printerInfo = @() foreach ($printer in $printers) { $printerName = $printer.Name $portName = $printer.PortName if ($portName -match 'IP_(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})') { $ipAddress = $Matches[1] $printerInfo += New-Object PSObject -Property @{ "打印机名称" = $printerName "IP地址" = $ipAddress } } } $printerInfo | Format-Table -AutoSize Write-Host "如果你的打印机未列出,请自行排查。" $printerIP = Read-Host "输入要添加${userName}到通讯录的打印机IP地址: " if ($printerIP -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') { $userExists = Get-LocalUser -Name "Scanner" -ErrorAction SilentlyContinue $isPasswordCorrect = $false # 验证Scanner用户密码是否正确 if ($userExists) { try { $context = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Machine) $isPasswordCorrect = $context.ValidateCredentials("Scanner", "Example123") } catch { Write-Host "验证用户密码时出错: $_" } } if ($userExists -and $isPasswordCorrect -and (Test-Path "C:\Users\Scanner")) { Write-Host "'Scanner'用户已存在,且密码为'Example123'。" $password = ConvertTo-SecureString "Example123" -AsPlainText -Force $folderScanAccount = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Scanner", $password } elseif ($userExists -and (Test-Path "C:\Users\Scanner")) { Write-Host "'Scanner'用户已存在,但密码不是'Example123'。" $password = ConvertTo-SecureString "Example123" -AsPlainText -Force New-LocalUser -Name "Scanner2" -Password $password -FullName "Scanner2" -Description "扫描备用账户" $folderScanAccount = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Scanner2", $password } elseif (!$userExists) { $password = ConvertTo-SecureString "Example123" -AsPlainText -Force New-LocalUser -Name "Scanner" -Password $password -FullName "Scanner" -Description "扫描专用账户" $folderScanAccount = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList "Scanner", $password } if ($folderScanAccount) { Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol-Client -NoRestart Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol-Deprecation -NoRestart Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update" -Name "RebootRequired" -Value 0 -Force $connectionProfiles = Get-NetConnectionProfile foreach ($profile in $connectionProfiles) { if ($profile.NetworkCategory -eq "Public" -and ($profile.InterfaceAlias -like "*Wi-Fi*" -or $profile.InterfaceAlias -like "*Ethernet*")) { Set-NetConnectionProfile -InterfaceIndex $profile.InterfaceIndex -NetworkCategory Private Write-Host "$($profile.InterfaceAlias)网络已切换为专用模式。" } } Write-Host "所有Wi-Fi和以太网网络已切换为专用模式(如适用)。" $share_name = "Scanner" $user_documents = [Environment]::GetFolderPath("MyDocuments") $path = Join-Path $user_documents "Scanner" if (!(Get-SmbShare | Where-Object { $_.Name -eq $share_name })) { if (!(Test-Path -Path $path -PathType Container)) { New-Item -Path $path -ItemType Directory } # 根据实际使用的用户设置权限 $targetUser = if ($isPasswordCorrect) { "Scanner" } else { "Scanner2" } net share $share_name=$path /grant:"$targetUser,FULL" /remark:"扫描共享文件夹" icacls $path /grant "$targetUser:(OI)(CI)RW" /inheritance:e /t } if (Get-SmbShare | Where-Object { $_.Name -eq $share_name }) { Write-Output "$share_name共享文件夹创建成功。" $UNCPath = "\\$env:COMPUTERNAME\$share_name" Install-Module -Name RicohAddressBook -Force -AllowClobber # 补充打印机管理凭证输入逻辑 if (!$credential) { $credential = Get-Credential -Message "输入打印机管理账户凭证" } Add-AddressBookEntry -Hostname $printerIP -Credential $credential -Name $userName -KeyDisplay $userName -Title1 "AB" -FolderScanPath $UNCPath -FolderScanAccount $folderScanAccount } else { Write-Output "$share_name共享文件夹创建失败。" } } } else { Write-Host "输入的IP地址无效。" } Read-Host "按回车键退出"
额外说明
- 替换了不可靠的密码验证方式,使用
PrincipalContext.ValidateCredentials实现准确的本地用户密码验证 - 补充了
Scanner用户密码正确时的folderScanAccount赋值,确保后续流程正常执行 - 修正了共享权限的目标用户,根据实际使用的账户动态设置
- 补充了打印机管理凭证的输入逻辑,修复原脚本中
$credential未定义的报错问题
内容的提问来源于stack exchange,提问作者Led Tower
相关产品推荐
相关产品推荐

