在 Get-ChildItem PowerShell 语句中排除子文件夹

Chr*_*ass 5 powershell get-childitem

我一直在尽最大努力更加熟悉 PowerShell,将其作为自动化许多常规任务的一种方式,以努力消除人为错误。我支持基于 Web 的应用程序,我当前的目标是创建一个脚本以将应用程序从一台服务器迁移到另一台服务器。到目前为止,我已经获得了在新服务器上安装应用程序的脚本,从旧服务器复制配置文件,并在进行任何其他更改之前备份所有文件。我需要做的最后一件事是搜索配置目录和所有子文件夹以替换主机名、IP 地址和目录位置的所有实例(如果新服务器上的驱动器盘符发生更改)有一个文件夹名为 X:\Website\Tools\Database\Upgrade,其中包含客户曾经使用过的每个版本的文件夹,并且该文件夹中包含数据库升级脚本。我无权更改此文件夹中的任何内容,坦率地说,我也不想更改 X:\Website\tools 中的任何内容。

我将这部分脚本编写如下:

#Replace all instances of hostname, IP address, and drive letter
$path = "\\$newip\$newdriveletter$\Website"
$exclude = @("$path\tools\*")
$files = get-childitem $path\*.* -recurse -exclude $exclude 
$files | %{
    (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -replace 
"${olddriveletter}:\Website", "${newDriveLetter}:\Website" | set-content 
$_.fullname
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,它会替换我想要它替换的所有内容,但它仍然抛出以下错误:

gc : Access to the path 
'\\10.5.17.60\E$\Website\Tools\Database\Upgrade\6.2.0' is denied.
At C:\Folder\Powershell\Migrate.ps1:72 char:6
+     (gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -repl ...
+      ~~~~~
     + CategoryInfo          : PermissionDenied: 
(\\10.5.17.60\E$...e\Upgrade\6.2.0:String) [Get-Content], 
UnauthorizedAccessException
    + FullyQualifiedErrorId : 
Run Code Online (Sandbox Code Playgroud)

我还了解到 -exclude 参数在 PowerShell 中几乎被破坏,并且不能很好地排除文件夹。建议将其格式化如下:

#Replace all instances of hostname, IP address, and drive letter
$path = "\\$newip\$newdriveletter$\Website"
$files = get-childitem $path\*.* -recurse | select-object -expandproperty 
fullname | where-object{$_ -notlike "\\tools\\"}
$files | %{
(gc $_) -replace $oldhost, $newhost -replace $oldip, $newip -replace "${olddriveletter}:\Website", "${newDriveLetter}:\Website" | set-content $_.fullname
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我运行这个时,我收到错误:

Set-Content : Cannot bind argument to parameter 'Path' because it is null.
At C:\Folder\Powershell\Migrate.ps1:72 char:151
+ ... \WebAccess", "${newDriveLetter}:\Website" | set-content $_.fullname
Run Code Online (Sandbox Code Playgroud)

所以基本上我已经实现了最终目标,但我真的很想在不出现任何错误的情况下做到这一点。如果人们开始运行这个并看到红色,他们可能会惊慌失措。所以我认为必须有一种方法来排除甚至查看这些文件夹。可能是一个 If 语句,但我不太确定如何格式化它。有什么建议么?

Ric*_*itt 6

如果你只是跑

get-childitem $path\*.* -recurse -exclude $exclude 
Run Code Online (Sandbox Code Playgroud)

您应该看到它仍然返回您尝试排除的文件夹。这是因为 get-childitem -exclude 不适用于容器。

相反尝试

$files = get-childitem $path\*.* -recurse | where-object{$_.fullname -notlike $exclude}
Run Code Online (Sandbox Code Playgroud)


Ric*_*itt 0

不确定 PS 版本是否有差异(我使用的是 4)..但我必须做一些调整才能使其正常工作。我的测试就是这样的...

$oldhost = "RBABBITT1"
$oldip = "192.168.1.21"
$olddriveletter = "C"

$newhost = "RBABBITT2"
$newip = "192.168.1.22"
$newdriveletter = "D"


$path = "\\$newip\$newdriveletter$\test1"
$exclude = "$path\tools\*"
$files = get-childitem $path -Recurse | where-object{$_.fullname -notlike $exclude -and $_.PSIsContainer -eq $false}
$files | %{
    (gc $_.FullName) -replace $oldhost, $newhost -replace $oldip, $newip -replace [regex]::Escape("${olddriveletter}:\Website"), "${newDriveLetter}:\Website" | set-content $_.fullname
}
Run Code Online (Sandbox Code Playgroud)