You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

远程非域PC共享文件夹CSV文件监控拷贝PowerShell脚本问题

解决思路:先建立带凭据的网络映射,再使用FileSystemWatcher

FileSystemWatcher本身并不支持直接传递凭据访问非域共享,因为它依赖系统已建立的网络连接上下文。所以核心解决方案是先通过凭据建立到目标共享的网络连接,之后FileSystemWatcher就能正常访问该共享了。

下面是修改后的完整脚本,包含凭据处理、网络映射建立、监控逻辑和连接清理:

# 1. 定义目标共享和相关参数
$remoteShareRoot = '\\remoteip\folder'  # 共享根目录,用于建立映射
$watchFolder = "$remoteShareRoot\subfolder"
$filter = '*.csv'
$destination = '\\mynetworkstorage\folder\'

# 2. 创建凭据对象(替换为你的实际账号信息)
$remotePCName = "remoteip"  # 目标PC的IP或计算机名
$username = "$remotePCName\你的共享账号"
$password = Read-Host "请输入共享账号的密码" -AsSecureString
$credential = New-Object System.Management.Automation.PSCredential ($username, $password)

try {
    # 3. 建立到目标共享的SMB映射(无需挂载盘符,仅建立连接上下文)
    Write-Host "正在建立到共享 $remoteShareRoot 的连接..."
    New-SmbMapping -RemotePath $remoteShareRoot -Credential $credential -Persistent $false | Out-Null

    # 4. 初始化FileSystemWatcher
    $fsw = New-Object IO.FileSystemWatcher $watchFolder, $filter -Property @{
        IncludeSubdirectories = $true
        NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
    }

    # 5. 注册文件创建事件(注意使用$using:引用外部变量)
    $onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
        $path = $Event.SourceEventArgs.FullPath
        $name = $Event.SourceEventArgs.Name
        $changeType = $Event.SourceEventArgs.ChangeType
        $timeStamp = $Event.TimeGenerated
        
        Write-Host "检测到文件 '$name' 已$changeType,时间:$timeStamp"
        try {
            Copy-Item $path -Destination $using:destination -Force -Verbose
            Write-Host "文件 '$name' 已成功拷贝到目标路径"
        } catch {
            Write-Error "拷贝文件 '$name' 失败:$_"
        }
    }

    Write-Host "监控已启动,正在等待新增CSV文件...按Ctrl+C停止"
    # 保持脚本运行,直到用户中断
    do {
        Start-Sleep -Seconds 1
    } while ($true)
} catch {
    Write-Error "初始化过程出错:$_"
} finally {
    # 6. 清理资源:停止监控并断开网络连接
    Write-Host "正在停止监控并清理连接..."
    Unregister-Event -SourceIdentifier FileCreated -ErrorAction SilentlyContinue
    $fsw.Dispose() -ErrorAction SilentlyContinue
    Remove-SmbMapping -RemotePath $remoteShareRoot -Force -ErrorAction SilentlyContinue
    Write-Host "资源已清理完成"
}

关键细节说明:

  • 网络映射的作用New-SmbMapping会在系统中建立一个带凭据的临时连接,让后续的FileSystemWatcher和Copy-Item操作能自动使用这个凭据访问共享,无需再次传递。
  • $using:变量引用:在Register-ObjectEventAction块中,无法直接访问外部脚本定义的变量(比如$destination),必须用$using:前缀来跨运行空间引用。
  • 资源清理:使用try/finally块确保即使脚本出错或被中断,也会停止监控并断开网络连接,避免残留无效的SMB映射。
  • 凭据安全:用Read-Host -AsSecureString输入密码,避免明文显示;如果需要自动化运行,可以将密码加密存储(比如用ConvertTo-SecureStringExport-Clixml),避免手动输入。

替代方案:使用传统的net use命令

如果你更习惯用net use,可以替换第3步的New-SmbMapping为:

# 转换SecureString为明文(仅用于net use,注意安全风险)
$plainPassword = [System.Net.NetworkCredential]::new("", $password).Password
net use $remoteShareRoot /user:$username $plainPassword /persistent:no

不过这种方式会将密码转为明文,安全性稍差,优先推荐New-SmbMapping

内容的提问来源于stack exchange,提问作者AdzzzUK

火山引擎 最新活动