1

Ok I'll try and keep this short.

First let me explain exactly what I am trying to get. If you open Windows Explorer and go to a network drive there is a DFS tab there(must have DFS enabled VIA the servers on the network so it may not be there).

In that tab there is a list called the "Referral List"... I want what is in that box. I believe this is the DFS or UNC, you can correct me it will help me.

What I have is the \domainname.com\something$\BUS\blah\myDriveHome but this is tied to something else in that box that contains the actual server that that share is setting on and that share is what I need to run a compliance check.

I cannot use an exe that is not package with Windows 7 not any other exe as we cannot distribute exes.

So what have I done... a VERY thorough search for things like DFS/UNC paths from the command line, powershell, and registry and no go. Command line "net use" only return the linked path and not the server so that is useless.

I only ever post a question when I hit a wall that is taking up to much programming time.

If anyone has an info it would be grateful.

enter image description here

Thanks

reddragon72
  • 191
  • 1
  • 3
  • 16

2 Answers2

0

I was able to steal the C# code in this answer here and make some modifications so it works with .Net 2.0, and use it within PowerShell:

$dfsCode = @'
using System;
using System.Runtime.InteropServices;

public static class Dfs
{
    private enum NetDfsInfoLevel
    {
        DfsInfo1 = 1,
        DfsInfo2 = 2,
        DfsInfo3 = 3,
        DfsInfo4 = 4,
        DfsInfo5 = 5,
        DfsInfo6 = 6,
        DfsInfo7 = 7,
        DfsInfo8 = 8,
        DfsInfo9 = 9,
        DfsInfo50 = 50,
        DfsInfo100 = 100,
        DfsInfo150 = 150,
    }

    [DllImport("netapi32.dll", SetLastError = true)]
    private static extern int NetApiBufferFree(IntPtr buffer);

    [DllImport("Netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int NetDfsGetInfo(
        [MarshalAs(UnmanagedType.LPWStr)] string DfsEntryPath, // DFS entry path for the volume
        [MarshalAs(UnmanagedType.LPWStr)] string ServerName,   // This parameter is currently ignored and should be NULL
        [MarshalAs(UnmanagedType.LPWStr)] string ShareName,    // This parameter is currently ignored and should be NULL.
        NetDfsInfoLevel Level,                                 // Level of information requested
        out IntPtr Buffer                                      // API allocates and returns buffer with requested info
        );

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct DFS_INFO_3
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string EntryPath;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string Comment;
        public int State;
        public int NumberOfStorages;
        public IntPtr Storage;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    private struct DFS_STORAGE_INFO
    {
        public int State;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ServerName;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string ShareName;
    }

    private static T GetStruct<T>(IntPtr buffer, int offset)where T:struct
    {
        T r = new T();
        r = (T) Marshal.PtrToStructure((IntPtr)((long)buffer + offset * Marshal.SizeOf(r)), typeof(T));
        return r;
    }

    public static string GetDfsInfo(string server)
    {
        string rval = null;
        IntPtr b;
        int r = NetDfsGetInfo(server, null, null, NetDfsInfoLevel.DfsInfo3, out b);
        if(r != 0)
        {
            NetApiBufferFree(b);

            // return passed string if not DFS
            return rval;
        }

        DFS_INFO_3 sRes = GetStruct<DFS_INFO_3>(b,0);
        if(sRes.NumberOfStorages > 0)
        {
            DFS_STORAGE_INFO sResInfo = GetStruct<DFS_STORAGE_INFO>(sRes.Storage,0);
            rval = string.Concat(@"\\", sResInfo.ServerName, @"\", sResInfo.ShareName, @"\");
        }

        NetApiBufferFree(b);

        return rval;
    }
}
'@

Add-Type -TypeDefinition $dfsCode

[Dfs]::GetDfsInfo('\\ad.domain.com\Share')

This code will work with PowerShell 2.0 which is included with Windows 7.

Community
  • 1
  • 1
briantist
  • 45,546
  • 6
  • 82
  • 127
  • let me add this in and see if I can use it for my case. I believe I have seen this on another site but this looks to be better documented. I'll get back to you in a day or so when I get a chance to implement it. Thanks! – reddragon72 Aug 08 '15 at 15:52
  • I could not get this to do anything. how do I get an output from it? and do I need to remove anything from the script above? – reddragon72 Aug 18 '15 at 13:16
  • @reddragon72 the last line is what would produce the output; that's how you would invoke it. Of course you need to replace the share path with your own. – briantist Aug 18 '15 at 15:43
  • 1
    So I did that with this. [Dfs]::GetDfsInfo('\\LOCAL.AD.MYBUSNESS.COM\AmeBUS$\XBUS\NATXVDIHOME06\USERSID') I changed a few items names of course but when I put that in there I get nothing back. – reddragon72 Aug 18 '15 at 15:55
0

I went another direction with the use of PSEXEC and DFSUtil to find the DFS info VIA the remote PC. Returns a lot of info but I filtered it in PowerShell after reading the file and matching the UNC. I would post the how to but I had to do some major adapting on my end with the info that is on a few other sites for DFSUtil and what to look for and PSExec. I will note this for PSEXEC:

cmd.exe /s /c C:\Temp\psexec.exe 2> $null

That "2> $null" will save you some headaches and your script crashing if the return is in the error channel. You will need to run it in the PS console though without that to catch the error, but when you have a script like mine performing 50+ system checks you don't want the whole thing to halt for just one error.

reddragon72
  • 191
  • 1
  • 3
  • 16