Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.2k views
in Technique[技术] by (71.8m points)

powershell - How can I query a temporary PS-Drive while returning files with a name relative to the drive?

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: \server01COMMONFolder

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
otepad.exe).get_Length() #OK
([IO.FileInfo]'X:System32
otepad.exe').get_Length() #Error

But Get-Item X:System32 otepad.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
otepad.exe).FullName
# C:WindowsSystem32
otepad.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
otepad.exe
# C:WindowsSystem32
otepad.exe

Same happens when you create the PowerShell drive, which point to some network path:

New-PSDrive Y FileSystem \ComputerShare
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 \ComputerShare -Persist|Format-Table *Root
# Root        : Z:
# DisplayRoot : \ComputerShare

As you can see, the Root will be not \ComputerShare 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...