我正在尝试创建一个脚本,我将在文件服务器中搜索非继承权限。因此,我遇到了文件名的260个字符限制。我看到的一个建议,我认为会有所帮助,有几次是创建一些非持久性PS驱动器,并且可以查询这些驱动程序。
问题是,当我对新的PS Drives使用Get-ChildItem
时,它使用完整的网络路径返回对象,使用我指定的名称而不是。
# Cycle the folders
Get-ChildItem $rootPath -Directory | select -first 1 | ForEach-Object{
$target = $_
# Create a PS Drive for each sub directory and get all the folders
[void](New-PSDrive -Name $target.Name -PSProvider FileSystem $target.FullName)
# Get the file objects.
Get-ChildItem "$($target.Name):\" -Recurse
}
我确信如果我用驱动器号创建了一些合适的持久性网络驱动器,我就不会遇到这个问题。
希望我没有错过,但Technet for New-PSDrive并未100%清楚这种情况。
我正在寻找一种方法来制作ps-drive并引用文件夹,同时返回相对于新驱动器名称的路径。考虑我制作的psdrive(G :)然后我的一个映射网络驱动器(M :)的输出。
PS M:\> Get-ChildItem G:\
Directory: \\server01\COMMON\Folder
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 6/18/2011 8:14 AM Folder 1
d---- 6/18/2011 8:14 AM Folder 2
PS M:\> Get-ChildItem M:\
Directory: M:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 5/8/2015 11:00 AM Backup
d---- 5/8/2015 11:00 AM covers
d---- 5/8/2015 11:00 AM drop
d---- 5/8/2015 11:00 AM Expense
我知道我的确切情况存在多种解决方法,但我想了解我使用New-PSDrive
显示的行为。
答案 0 :(得分:7)
看起来你混合了两个不同的东西:PowerShell路径和Provider路径。 PowerShell路径在PowerShell外部不可见。
New-PSDrive X FileSystem C:\Windows
(Get-Item X:\System32\notepad.exe).get_Length() #OK
([IO.FileInfo]'X:\System32\notepad.exe').get_Length() #Error
但是Get-Item X:\System32\notepad.exe
设法创建了一个FileInfo
对象,它代表了一些文件。那么,生成的FileInfo
对象表示哪个文件?
(Get-Item X:\System32\notepad.exe).FullName
# C:\Windows\System32\notepad.exe
由于FileInfo
对象对PowerShell驱动器X:
一无所知,因此它必须存储一个路径,该路径在内部使用它可以理解的文件系统API。您可以使用Convert-Path
cmdlet将PowerShell路径转换为提供程序路径:
Convert-Path X:\System32\notepad.exe
# C:\Windows\System32\notepad.exe
创建PowerShell驱动器时会发生相同的情况,该驱动器指向某个网络路径:
New-PSDrive Y FileSystem \\Computer\Share
Get-ChildItem Y:\
返回的FileInfo
和DirectoryInfo
对象对Y:
一无所知,因此他们无法拥有相对于该PowerShell驱动器的路径。内部使用的文件系统API无法理解它们。
使用-Persist
选项时,情况会发生变化。在这种情况下,将创建实际映射的驱动器,这可以通过PowerShell之外的文件系统API来理解。
New-PSDrive Z FileSystem \\Computer\Share -Persist|Format-Table *Root
# Root : Z:\
# DisplayRoot : \\Computer\Share
正如您所看到的,Root
不是\\Computer\Share
,而是New-PSDrive
cmdlet,Z:\
。由于Z:
在这种情况下是真正的驱动器,FileInfo
或DirectoryInfo
cmdlet返回的Get-Item
和Get-ChildItem
对象可以有相对于它的路径。
答案 1 :(得分:1)
function Get-FreeDriveLetter {
$drives = [io.driveinfo]::getdrives() | % {$_.name[0]}
$alpha = 65..90 | % { [char]$_ }
$avail = diff $drives $alpha | select -ExpandProperty inputobject
$drive = $avail[0] + ':'
$drive
}
$file = gi 'C:\temp\file.txt'
$fullname = $file.FullName
if ($fullname.length -gt 240) {
$drive = Get-FreeDriveLetter
$path = Split-Path $fullname
subst $drive $path
$subst = $true
rv path
$fullname = Join-Path $drive $(Split-Path $fullname -Leaf)
}
$fullname