Powershell 从UNC路径获取DFS服务器名称和本地路径

Powershell 从UNC路径获取DFS服务器名称和本地路径,powershell,microsoft-distributed-file-system,Powershell,Microsoft Distributed File System,我正在Windows Server 2012上工作,默认情况下,它附带了各种功能 我试图做的是获取特定UNC共享的ComputerName和local path,该共享由域上的其他DFS服务器(Win Srv 2008 R2)托管 一个例子: Get-DfsnFolderTarget -Path '\\domain.net\share\folder\' ComputerName = 'Server1' Path = 'E\Home\folder' 预期结果: Get-Dfsn

我正在Windows Server 2012上工作,默认情况下,它附带了各种功能

我试图做的是获取特定UNC共享的
ComputerName
local path
,该共享由域上的其他DFS服务器(Win Srv 2008 R2)托管

一个例子:

Get-DfsnFolderTarget -Path '\\domain.net\share\folder\'
ComputerName = 'Server1'
Path         = 'E\Home\folder'
预期结果:

Get-DfsnFolderTarget -Path '\\domain.net\share\folder\'
ComputerName = 'Server1'
Path         = 'E\Home\folder'
我不是一个真正的网络工程师,但我似乎找不到一种基于UNC路径检索这些信息的方法。每次尝试上述CmdLet时,我都会收到一个错误:

Get-DfsnFolderTarget : Cannot get DFS folder properites on "\\domain.net\share\folder\"
At line:1 char:1
+ Get-DfsnFolderTarget -Path '\\domain.net\share\folder\'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (MSFT_DfsNamespaceFolderTarget:ROOT\Microsoft\...aceFolderTarget) [Ge 
   t-DfsnFolderTarget], CimException
    + FullyQualifiedErrorId : Windows System Error 1168,Get-DfsnFolderTarget

Get-DfsnFolderTarget : The requested object could not be found.
At line:1 char:1
+ Get-DfsnFolderTarget -Path '\\domain.net\share\folder\'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (MSFT_DfsNamespaceFolderTarget:ROOT\Microsoft\...aceFolderTarget) [Ge 
   t-DfsnFolderTarget], CimException
    + FullyQualifiedErrorId : MI RESULT 6,Get-DfsnFolderTarget
当尝试
测试路径\\domain.net\share\folder\
时,它确实会说可以找到它。所以我真的不明白

我正在尝试检索此信息(
ComputerName
local path
):

通过几个小时的谷歌搜索和调整一些东西,我解决了自己的问题。这就是我为其他感兴趣的人所做的:

    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])
                }
            }
        }
    }
函数获取详细信息{
[CmdLetBinding()]
Param(
[参数(必需,位置=0)]
[PSCredential]$Credentials,
[参数(必需,ValueFromPipeline,位置=1)]
[验证说明]({
if(测试路径-LiteralPath$\路径类型容器){$true}
否则{throw“找不到路径“$”}
})]
[String[]]$Path
)
开始{
$signature=@'
使用制度;
使用System.Collections.Generic;
使用系统、管理、自动化;
使用System.Runtime.InteropServices;
公共类Win32Api
{
[DllImport(“netapi32.dll”,SetLastError=true)]
私有静态外部int NetApiBufferFree(IntPtr缓冲区);
[DllImport(“Netapi32.dll”,CharSet=CharSet.Unicode,SetLastError=true)]
私有静态外部int NetDfsGetClientInfo
(
[Marshallas(UnmanagedType.LPWStr)]字符串入口路径,
[Marshallas(UnmanagedType.LPWStr)]字符串服务器名,
[Marshallas(UnmanagedType.LPWStr)]字符串共享名,
整数级,
ref IntPtr缓冲区
);
公共结构DFS\u信息\u 3
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串入口路径;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串评论;
公共UInt32州;
公共存储单元32个;
公共IntPtr存储;
}
公共结构DFS\u存储\u信息
{
国家公共部门;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串ServerName;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串共享名;
}
公共静态列表NetDfsGetClientInfo(字符串DfsPath)
{
IntPtr buffer=新的IntPtr();
List returnList=新列表();
尝试
{
int result=NetDfsGetClientInfo(DfsPath,null,null,3,ref buffer);
如果(结果!=0)
{
抛出(新系统异常(“获取DFS信息时出错”);
}
其他的
{
DFS_INFO_3 dfsInfo=(DFS_INFO_3)Marshal.ptr结构(缓冲区,类型(DFS_INFO_3));
对于(int i=0;i