【问题标题】:Powershell script to copy old files and create shortcuts用于复制旧文件并创建快捷方式的 Powershell 脚本
【发布时间】:2021-05-12 10:26:07
【问题描述】:

我正在使用 powershell 创建一个存根脚本。我对这个脚本的意图是将过去 x 时间段内未写入的任何数据复制到新位置,检查文件是否已复制,在其原始位置创建“存档”文件的快捷方式,并最终删除旧文件(我还没有写这部分)。以下是我到目前为止所拥有的。我现在遇到的问题是创建了一个快捷方式,但是所有快捷方式都保存到 C:\Temp 目录而不是任何子文件夹中;如果那是原始文件的存储位置。我认为我的问题在于 $link,我需要拆分路径并加入它们,但我不确定。非常感谢任何帮助!

# Variables
$Original = "C:\Temp"
$Archive = "\\data\users\Temp"

Get-ChildItem -Path $Original -Recurse |
Where-Object {
    $_.LastWriteTime -lt [datetime]::Now.AddMinutes(-1)
} | Copy-Item -Destination $Archive -Recurse -force

$sourceFiles = Get-ChildItem $Original -Recurse | Where-Object { $_.LastWriteTime -lt [datetime]::Now.AddMinutes(-1) } | Select Name, Fullname
$destFiles = Get-ChildItem $Archive -Recurse | Select Name, Fullname

$Comparison = Compare-Object $sourceFiles.name $destFiles.name 

If ($comparison.sideindicator -ne "<=") {
    get-childitem $Archive -Recurse | where { $_.PsIsContainer -eq $false } | ForEach-Object {
        $path = '"' + $_.FullName + '"'
        $link = $Original + '\' + $_.Basename + '.lnk'
        $wshell = New-Object -ComObject WScript.Shell
        $shortcut = $wshell.CreateShortcut($link)
        $shortcut.TargetPath = $path
        $shortcut.Save()
    }
}

If ($comparison.sideindicator -eq "<=") {
    $comparison.inputobject, $sourceFiles.fullname | Out-File  'C:\ScriptLogs\stubbing.csv' -Force
}

【问题讨论】:

    标签: powershell filepath wscript.shell


    【解决方案1】:

    这是有问题的代码:

    $link = $Original + '\' + $_.Basename + '.lnk'
    

    Basename 只是没有路径的文件名部分,因此 .lnk 文件直接在顶级目录中结束。

    你必须像这样使用相对路径:

    $RelativePath = [IO.Path]::GetRelativePath( $Archive, $_.FullName ) 
    $link = [IO.Path]::ChangeExtension( "$Original\$RelativePath", 'lnk' ) 
    

    GetRelativePath 需要 .NET 5。要支持较旧的 .NET 版本,您可以使用:

    Push-Location $Archive
    try     { $RelativePath = Resolve-Path -Relative $_.FullName }
    finally { Pop-Location }
    

    Resolve-Path -Relative 使用当前位置作为基准。所以我们使用Push-Location来临时改变当前位置。 try / finally 用于确保在Resolve-Path 抛出异常的情况下(例如,当您设置了$ErrorActionPreference = 'Stop')时恢复原始位置。


    虽然代码可能会这样工作,但我认为可以这样重构:

    • 单个 Get-ChildItem 调用来存储要移动到数组中的文件(您当前的 $sourceFiles = ... 行)
    • foreach 循环遍历此数组以移动每个文件并创建快捷方式。
    • 我认为Compare-Object 甚至没有必要,但也许我遗漏了一些东西。

    目前您正在多次迭代相同的目录,效率不高且重复代码很多。

    【讨论】:

    • 感谢您对 Zett 的帮助。请原谅我的无知。当我使用: $RelativePath = [IO.Path]::GetRelativePath( $Archive, $_.FullName ) 我收到错误 方法调用失败,因为 [System.IO.Path] 不包含名为“GetRelativePath”的方法。当我尝试 $RelativePath = Resolve-Path "$Archive, $_.FullName" -Relative 我收到错误“找不到路径...因为它不存在。
    • @dturner [IO.Path]::GetRelativePath 需要 .NET 5。我为 Resolve-Path 添加了代码示例。
    猜你喜欢
    • 2022-10-17
    • 1970-01-01
    • 2021-07-10
    • 2015-04-27
    • 1970-01-01
    • 2020-12-19
    • 1970-01-01
    • 2014-11-23
    • 2012-03-30
    相关资源
    最近更新 更多