问题
I am trying to create a script where I will be searching the file servers for non inherited permissions. I have run into the 260 character limit for file names as a result. A suggestion I saw, that I thought would help, a couple of times was to create some non persistent PS Drives a couple of levels deep and query those.
Problem is when I use Get-ChildItem
against the new PS Drives it is returning object with the full network path and not using the name I assigned it.
# 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
}
I am sure that if I created some proper persistent network drives with a drive letter I would not have this issue.
Hopefully I just didn't miss it but Technet for New-PSDrive was not 100% clear about this scenario.
I am looking for a way to make ps-drive and reference there folders while returning paths relative to the new drive name. Consider the output from a psdrive I made (G:) then one of my mapped network drives (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
I am aware that multiple workarounds exists for my exact situation but I would like to understand the behavior that I am showing with New-PSDrive
.
回答1:
Looks like you are mixing up two different things: PowerShell path and Provider path. PowerShell paths are not visible outside of 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
But Get-Item X:\System32\notepad.exe
managed to create a FileInfo
object, which represents some file. So, what file is represented by the resulting FileInfo
object?
(Get-Item X:\System32\notepad.exe).FullName
# C:\Windows\System32\notepad.exe
Since the FileInfo
object knows nothing about PowerShell drive X:
, it has to store a path, which internally uses the file system API which it can understand. You can use Convert-Path
cmdlet to convert PowerShell path to Provider path:
Convert-Path X:\System32\notepad.exe
# C:\Windows\System32\notepad.exe
Same happens when you create the PowerShell drive, which point to some network path:
New-PSDrive Y FileSystem \\Computer\Share
Get-ChildItem Y:\
Returned FileInfo
and DirectoryInfo
objects know nothing about Y:
, so they can not have paths relative to that PowerShell drive. Internally used file system API will not understand them.
Things changes when you use the -Persist
option. In that case real mapped drives will be created, which can be understood by file system API outside of PowerShell.
New-PSDrive Z FileSystem \\Computer\Share -Persist|Format-Table *Root
# Root : Z:\
# DisplayRoot : \\Computer\Share
As you can see, the Root
will be not \\Computer\Share
as you ask in New-PSDrive
cmdlet, but Z:\
. Since Z:
is a real drive in this case, FileInfo
and DirectoryInfo
objects returned by Get-Item
or Get-ChildItem
cmdlet can have paths relative to it.
回答2:
haven't tested, but if you're not opposed to using 'subst' something like this might work for you
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
来源:https://stackoverflow.com/questions/34812349/how-can-i-query-a-temporary-ps-drive-while-returning-files-with-a-name-relative