我通过几个小时的谷歌搜索和调整一些东西解决了我自己的问题。对于其他感兴趣的人来说,这就是我最终得到的结果:
Function Get-DFSDetails {
<#
.SYNOPSIS
Gets DFS details for a UNC path.
.DESCRIPTION
The Get-DFSDetails CmdLet gets DFS details like DFS Server name, DFS Share name and the local path on the DFS Server for a specific UNC path.
.PARAMETER Credentials
PowerShell credential object used to connect to the DFS Server to retrieve the local path on the server.
.PARAMETER Path
Specifies a UNC path for the folder.
.EXAMPLE
Get-DFSDetails -Path '\\domain.net\HOME\Bob' -Credentials $Credentials
Gets the DFS details for the UNC path '\\domain.net\HOME\Bob'
Path : \\domain.net\HOME\Bob
ComputerName : SERVER1.DOMAIN.NET
ComputerPath : E:\HOME\Bob
ShareName : HOME
.EXAMPLE
'\\domain.net\HOME\Mike', '\\domain.net\HOME\Jake' | Get-DFSDetails -Credentials $Credentials
Gets the DFS details for the UNC paths '\\domain.net\HOME\Mike' and '\\domain.net\HOME\Jake'
Path : \\domain.net\HOME\Mike
ComputerName : SERVER1.DOMAIN.NET
ComputerPath : E:\HOME\Mike
ShareName : HOME
Path : \\domain.net\HOME\Jake
ComputerName : SERVER2.DOMAIN.NET
ComputerPath : E:\HOME\Jake
ShareName : HOME
.NOTES
CHANGELOG
2015/10/27 Function born #>
[CmdLetBinding()]
Param (
[Parameter(Mandatory, Position=0)]
[PSCredential]$Credentials,
[Parameter(Mandatory, ValueFromPipeline, Position=1)]
[ValidateScript({
if (Test-Path -LiteralPath $_ -PathType Container) {$true}
else {throw "Could not find path '$_'"}
})]
[String[]]$Path
)
Begin {
$signature = @'
using System;
using System.Collections.Generic;
using System.Management.Automation;
using System.Runtime.InteropServices;
public class Win32Api
{
[DllImport("netapi32.dll", SetLastError = true)]
private static extern int NetApiBufferFree(IntPtr buffer);
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int NetDfsGetClientInfo
(
[MarshalAs(UnmanagedType.LPWStr)] string EntryPath,
[MarshalAs(UnmanagedType.LPWStr)] string ServerName,
[MarshalAs(UnmanagedType.LPWStr)] string ShareName,
int Level,
ref IntPtr Buffer
);
public struct DFS_INFO_3
{
[MarshalAs(UnmanagedType.LPWStr)]
public string EntryPath;
[MarshalAs(UnmanagedType.LPWStr)]
public string Comment;
public UInt32 State;
public UInt32 NumberOfStorages;
public IntPtr Storages;
}
public struct DFS_STORAGE_INFO
{
public Int32 State;
[MarshalAs(UnmanagedType.LPWStr)]
public string ServerName;
[MarshalAs(UnmanagedType.LPWStr)]
public string ShareName;
}
public static List<PSObject> NetDfsGetClientInfo(string DfsPath)
{
IntPtr buffer = new IntPtr();
List<PSObject> returnList = new List<PSObject>();
try
{
int result = NetDfsGetClientInfo(DfsPath, null, null, 3, ref buffer);
if (result != 0)
{
throw (new SystemException("Error getting DFS information"));
}
else
{
DFS_INFO_3 dfsInfo = (DFS_INFO_3)Marshal.PtrToStructure(buffer, typeof(DFS_INFO_3));
for (int i = 0; i < dfsInfo.NumberOfStorages; i++)
{
IntPtr storage = new IntPtr(dfsInfo.Storages.ToInt64() + i * Marshal.SizeOf(typeof(DFS_STORAGE_INFO)));
DFS_STORAGE_INFO storageInfo = (DFS_STORAGE_INFO)Marshal.PtrToStructure(storage, typeof(DFS_STORAGE_INFO));
PSObject psObject = new PSObject();
psObject.Properties.Add(new PSNoteProperty("State", storageInfo.State));
psObject.Properties.Add(new PSNoteProperty("ServerName", storageInfo.ServerName));
psObject.Properties.Add(new PSNoteProperty("ShareName", storageInfo.ShareName));
returnList.Add(psObject);
}
}
}
catch (Exception e)
{
throw(e);
}
finally
{
NetApiBufferFree(buffer);
}
return returnList;
}
}
'@
if (-not ('Win32Api' -as [Type])) {
Add-Type -TypeDefinition $signature
}
}
Process {
foreach ($P in $Path) {
Try {
# State 6 notes that the DFS path is online and active
$DFS = [Win32Api]::NetDfsGetClientInfo($P) | Where-Object { $_.State -eq 6 } |
Select-Object ServerName, ShareName
$SessionParams = @{
Credential = $Credentials
ComputerName = $DFS.ServerName
SessionOption = New-CimSessionOption -Protocol Dcom
}
$CimParams = @{
CimSession = New-CimSession @SessionParams
ClassName = 'Win32_Share'
}
$LocalPath = Get-CimInstance @CimParams | Where-Object Name -EQ $DFS.ShareName |
Select-Object -ExpandProperty Path
[PSCustomObject][Ordered]@{
Path = $P
ComputerName = $DFS.ServerName
ComputerPath = $LocalPath + ($P -split $DFS.ShareName, 2)[1]
ShareName = $DFS.ShareName
}
}
Catch {
Write-Error $Error[0].Exception.Message
$Global:Error.Remove($Global:Error[0])
}
}
}
}