Lately I was tasked to do a lot of Environment Management on user login which in Systems or Network Admin terms are called login scripts, but I am not a Systems nor a Network Admin but a developer by heart so I like things a bit more organized when I do my coding. I am not saying that there is something wrong with Powershell, VB Scripts, Batch Files or Command Files. I just like my stuff organized so I prefer to do it under a .NET Environment simply because:
- I can have versioning control. (You can do this as well with TXT but with Visual Studio it is integrated)
- It can be developed in a team environment.
- Codes are compiled so no Admins can just fiddle around with it.
- Intellisense!!!
- And its easier for me.
- Debugging is easier, I don't have to MsgBox everytime.
It may not be as fast as developing a normal script but way much organized, just imagine you have 30+ batch files that have dependencies with each other with at least 1000 lines of codes, imagine managing it.
Now one of those tasks that I am talking about is mapping of network drives that depends on which AD Groups you are joined in. So I saved my variables in SQL and extract those on runtime, managing the variables is also easy if it's in SQL (you can just create an interface to do this). To map the drives, I had used the Windows Networking Functions of which in this post I had used 2 functions, namely WNetAddConnection2
and WNetCancelConnection2
.
The WNetAddConnection2
function makes a connection to a network resource and the WNetCancelConnection2
function cancels an existing network connection. It's really simple to do this and here is the code.
public class DriveSettings
{
private enum ResourceScope
{
RESOURCE_CONNECTED = 1,
RESOURCE_GLOBALNET,
RESOURCE_REMEMBERED,
RESOURCE_RECENT,
RESOURCE_CONTEXT
}
private enum ResourceType
{
RESOURCETYPE_ANY,
RESOURCETYPE_DISK,
RESOURCETYPE_PRINT,
RESOURCETYPE_RESERVED
}
private enum ResourceUsage
{
RESOURCEUSAGE_CONNECTABLE = 0x00000001,
RESOURCEUSAGE_CONTAINER = 0x00000002,
RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
RESOURCEUSAGE_SIBLING = 0x00000008,
RESOURCEUSAGE_ATTACHED = 0x00000010
}
private enum ResourceDisplayType
{
RESOURCEDISPLAYTYPE_GENERIC,
RESOURCEDISPLAYTYPE_DOMAIN,
RESOURCEDISPLAYTYPE_SERVER,
RESOURCEDISPLAYTYPE_SHARE,
RESOURCEDISPLAYTYPE_FILE,
RESOURCEDISPLAYTYPE_GROUP,
RESOURCEDISPLAYTYPE_NETWORK,
RESOURCEDISPLAYTYPE_ROOT,
RESOURCEDISPLAYTYPE_SHAREADMIN,
RESOURCEDISPLAYTYPE_DIRECTORY,
RESOURCEDISPLAYTYPE_TREE,
RESOURCEDISPLAYTYPE_NDSCONTAINER
}
[StructLayout(LayoutKind.Sequential)]
private struct NETRESOURCE
{
public ResourceScope oResourceScope;
public ResourceType oResourceType;
public ResourceDisplayType oDisplayType;
public ResourceUsage oResourceUsage;
public string sLocalName;
public string sRemoteName;
public string sComments;
public string sProvider;
}
[DllImport("mpr.dll")]
private static extern int WNetAddConnection2
(ref NETRESOURCE oNetworkResource, string sPassword,
string sUserName, int iFlags);
[DllImport("mpr.dll")]
private static extern int WNetCancelConnection2
(string sLocalName, uint iFlags, int iForce);
public static void MapNetworkDrive(string sDriveLetter, string sNetworkPath)
{
if (sNetworkPath.Substring(sNetworkPath.Length - 1, 1) == @"\")
{
sNetworkPath = sNetworkPath.Substring(0, sNetworkPath.Length - 1);
}
NETRESOURCE oNetworkResource = new NETRESOURCE();
oNetworkResource.oResourceType = ResourceType.RESOURCETYPE_DISK;
oNetworkResource.sLocalName = sDriveLetter + ":";
oNetworkResource.sRemoteName = sNetworkPath;
if (IsDriveMapped(sDriveLetter))
{
DisconnectNetworkDrive(sDriveLetter, true);
}
WNetAddConnection2(ref oNetworkResource, null, null, 0);
}
public static int DisconnectNetworkDrive(string sDriveLetter, bool bForceDisconnect)
{
if (bForceDisconnect)
{
return WNetCancelConnection2(sDriveLetter + ":", 0, 1);
}
else
{
return WNetCancelConnection2(sDriveLetter + ":", 0, 0);
}
}
public static bool IsDriveMapped(string sDriveLetter)
{
string[] DriveList = Environment.GetLogicalDrives();
for (int i = 0; i < DriveList.Length; i++)
{
if (sDriveLetter + ":\\" == DriveList[i].ToString())
{
return true;
}
}
return false;
}
}