Tag Archives: MapNetworkDrive

Powershell module to MapNetworkDrive

At my work, every few days I have to change the user and connect to a network drive. The mapping process every time used to be little bit difficult. I have created some powershell modules which helped me in this process. This is for my reference and if it helps others that’s great:
I have powershell 2.0 so the modules need to be created in VS 2008 for binary type modules, one can create powershell scripts and imports them as modules too. I wrote it in VS 2008, you need to add reference to System.Management and System.Management.Automation.dll(this is in powershell folder).

I wrote 4 different commandlets in this module, each will perform a different functionality.
Get-Drives – Gets all the logical drives and network paths
Get-FreeDriveLetter – Gets the available drive letter in the descending order which can be used.
Map-AuthNetworkDrive – Maps the network drive with the provided credentials or default credentials
Map-DisconnectNetworkDrive – Removes the map

Get-Drives

    [Cmdlet(VerbsCommon.Get, "Drives")]
    public class GetDrives: PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                var drives = CommonMethods.GetDrives();

                this.WriteObject(drives, true);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }

        }
               
    }

    //CommonMethods.GetDrives
 internal static IEnumerable<object> GetDrives2()
        {
            IList<object> driveInfo = new List<object>();
            try
            {
                SelectQuery query = new SelectQuery("Select DeviceID, DriveType, ProviderName From Win32_LogicalDisk");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
                foreach(ManagementObject disk in searcher.Get())
                {
                    driveInfo.Add(new { DeviceID = disk["DeviceID"], DriveType = (DiskType)disk["DriveType"], ProviderName = disk["ProviderName"] });
                }
            }
            catch (Exception ex)
            {
                throw ex;

            }

            return driveInfo;
        }

  public enum DiskType : uint
    {
        Unknown = 0,
        RemovableDisk = 2,
        LocalDisk = 3,
        NetworkDrive = 4,
        CompactDisk = 5,
        RAMDisk = 6
    }

Get-FreeDriveLetter

   [Cmdlet(VerbsCommon.Get, "FreeDriveLetter")]
    public class GetFreeDriveLetter : PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                string freeDrive = CommonMethods.GetFreeDriveLetter();

                this.WriteObject(freeDrive);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }
        }
    }

   //in CommonMethods.GetFreeDriveLetter method
      internal static string GetFreeDriveLetter()
        {
            string freeDrive = "";
            string[] driveLetters = { "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:" };
            var drives = System.IO.DriveInfo.GetDrives().Select(x => x.Name.Replace("\\", ""));
       
            foreach (var s in driveLetters.Reverse())
            {
                if (drives.Contains(s))
                {
                    freeDrive = "";
                }
                else
                {
                    freeDrive = s;
                    break;
                }
            }

            return freeDrive;
        }

For map and unmap I used Windows Script Host object model reference(IWshRuntimeLibrary)

     [Cmdlet("Map","AuthNetworkDrive")]
    public class MapNetworkDrive: PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0,ValueFromPipeline=false)]
        public string UNCPath { get; set; }

        [Parameter(Mandatory=false, Position=1)]
        public PSCredential Credential { get; set; }

        protected override void ProcessRecord()
        {
            try
            {
                WshNetwork network = new WshNetwork();
                if (Credential == null)
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, false);
                }
                else
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, true, Credential.UserName, Credential.GetNetworkCredential().Password);
                }
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001",ErrorCategory.MetadataError, null));
            }
        }
    }

    [Cmdlet("Map", "DisconnectNetworkDrive")]
    public class UnMapNetworkDrive : PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0)]
        public string DriveName { get; set; }

        protected override void ProcessRecord()
        {

            try
            {
                
                    IWshRuntimeLibrary.WshNetwork network = new IWshRuntimeLibrary.WshNetwork();
                    network.RemoveNetworkDrive(DriveName, true, true);
                
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.MetadataError, null));
            }
        }
    }

Once the build, you can import the module from powershell ise

Import-Module 'module dll path'

this will be available for that session. One can copy to the powershell module path, so that it can be available all the time.