使用 $PSScriptRoot - 如果存在则替换驱动器号和子文件夹

问题描述 投票:0回答:1

我对使用

$PSScriptRoot
变量有疑问。一点背景:我有一个 BAT 进程,它搜索特定名称的脚本,并在任何地方运行它,
$PSScriptRoot
用于获取 PS1 所在的路径。

在该设置中,清除垃圾文件非常有效。现在,我想做一些类似的事情,但有一点不同——我想用同一个脚本搜索

$PSScriptRoot
并找到所有符合我定义的参数的文件——我们称之为
$searchFile
——然后移动所有文件除了最新的备份文件夹。问题是,这些可能有两个位置,我需要从
$PSScriptRoot
.

构建备份文件夹的文件路径

所以这是设置:

$sourceDir=$PSScriptRoot
// As an example from one drive: $sourceDir = "H:\Project Files\Subfolder 1"
// An example from another drive: $sourceDir = "U:\MainFolder1\Project Files\Subfolder 1"
$targetDir= ???
// The file path I need to be able to get from both these $sourceDir variables: "H:\Deep Storage\Project Files\Subfolder1"
$search = "Project1-*.prproj"

这就是我想要它做的:

$numFiles = Get-ChildItem $sourceDir -Filter $search | Measure-Object | %{$_.Count};
Write-Host "$numFiles files present matching parameters, proceeding with cleanup." -ForegroundColor White -BackgroundColor DarkGreen;

If ($numFiles -gt 1) {
    Write-Host "Checking if TARGETDIR exists, please wait..." -ForegroundColor White -BackgroundColor DarkGreen -NoNewLine;
    If(!(test-path $targetDir))
    {
          Write-Host "folder not found, creating." -ForegroundColor White -BackgroundColor DarkGreen; 
          New-Item -ItemType Directory -Force -Path $targetDir
    } else {
          Write-Host "directory exists. File transfer in progress." -ForegroundColor White -BackgroundColor DarkGreen; 
    }
    Get-ChildItem -Path $sourceDir -Filter $search | Sort-Object CreationTime -Descending | 
        Select-Object -Skip 1 | Move-Item -Destination $targetDir -Force -Verbose
} else {
    Write-Host "Only one file present matching parameters, aborting run." -ForegroundColor White -BackgroundColor DarkYellow;
}

它的作用是计算

$PSScriptRoot
中符合条件的文件数量,如果只有一个则什么都不做;如果有两个或更多,它会将除最新的一个以外的所有内容移动到备份目录并保留目录结构。在这来自的脚本中,我指定了两个变量,如下所示:

$sourceDir = "H:\MainFolder1" //or "U:\TopFolder\MainFolder1"
$targetDir = "H:\Deep Storage\MainFolder1"

这足以让它做我想做的事。它们都进入备份目录中的同一个位置。使用

$PSScriptRoot
意味着我不能那样做——所以我必须给 Powershell 一些具体的说明。

所以基本上,我想告诉 Powershell“如果路径以此驱动器号开头,请将驱动器号替换为备份目录的根目录”,以及“如果路径以此驱动器号和文件夹名称开头,请将其替换为备份目录的根目录。”

换句话说,如果

$PSScriptRoot
以“H:\MainFolder”开头,我希望 Powershell 将其替换为“H:\Deep Storage\MainFolder”,如果它以“U:\TopFolder\MainFolder”开头,则将其更改为“H:\Deep Storage\MainFolder”。问题是,我对 PowerShell 语法的掌握不够好,无法做到这一点。

我很确定这是一件简单的事情,但我还没有找到任何人这样做的例子,我不知道从哪里开始。

powershell variables
1个回答
0
投票

换句话说,如果 $PSScriptRoot 以“H:\MainFolder”开头,我希望 Powershell 将其替换为“H:\Deep Storage\MainFolder”,如果它以“U:\TopFolder\MainFolder”开头,则更改到“H:\Deep Storage\MainFolder”。

假设放置脚本的所有目录都命名为

MainFolder
,或者您希望
H:\Deep Storage\
下的目标目录始终与脚本目录同名:

$targetDir = Join-Path 'H:\Deep Storage' (Split-Path -Leaf $PSScriptRoot)

如果对于 $PSScriptRoot

subtree
中的任何给定文件,您希望使用保留 relative 路径的目标路径,创建目标目录。按需:

$targetRootDir = Join-Path 'H:\Deep Storage' (Split-Path -Leaf $PSScriptRoot)

# ...

... | Move-Item -WhatIf -Verbose -Force -Destination {
  $targetDir = New-Item -Type Directory -Force (Join-Path $targetRootdir $_.DirectoryName.Substring($PSScriptRoot.Length))
  Join-Path $targetDir.FullName $_.Name
}

注意:上面命令中的

-WhatIf
常用参数previews操作。删除
-WhatIf
并在您确定操作将执行您想要的操作后重新执行。

这就是我认为你想要的完整拼写:

$targetRootDir = Join-Path 'H:\Deep Storage' (Split-Path -Leaf $PSScriptRoot)

$files = Get-ChildItem $sourceDir -Filter $search
Write-Host "$($files.Count) files present matching parameters, proceeding with cleanup." -ForegroundColor White -BackgroundColor DarkGreen

if ($files.Count -gt 1) {
    $files | 
      Sort-Object CreationTime -Descending | 
        Select-Object -Skip 1 | 
        Move-Item -WhatIf -Verbose -Force -Destination {
          $targetDir = New-Item -Type Directory -Force (Join-Path $targetRootdir $_.DirectoryName.Substring($PSScriptRoot.Length))
          Join-Path $targetDir.FullName $_.Name
        }        
} else {
    Write-Host "Only one file present matching parameters, aborting run." -ForegroundColor White -BackgroundColor DarkYellow
}
© www.soinside.com 2019 - 2024. All rights reserved.