title: Connecting to a network drive programmatically and caching credentials
body: <p>I'm finally set up to be able to work from home via VPN (using Shrew as a client), and I only have one annoyance. We use some batch files to upload config files to a network drive. Works fine from work, and from my team lead's laptop, but both of those machines are on the domain. My home system is not, and won't be, so when I run the batch file, I get a ton of "invalid drive" errors because I'm not a domain user.</p>
  
  <p>The solution I've found so far is to make a batch file with the following:</p>
  
  <pre><code>explorer \\MACHINE1
  explorer \\MACHINE2
  explorer \\MACHINE3
  </code></pre>
  
  <p>Then manually login to each machine using my domain credentials as they pop up. Unfortunately, there are around 10 machines I may need to use, and it's a pain to keep entering the password if I missed one that a batch file requires.</p>
  
  <p>I'm looking into using the answer to <a href="https://stackoverflow.com/questions/158492/c-network-login">this question</a> to make a little C# app that'll take the login info once and login programmatically. Will the authentication be shared automatically with Explorer, or is there anything special I need to do? If it does work, how long are the credentials cached?</p>
  
  <p>Is there an app that does something like this automatically?</p>
  
  <p>Unfortunately, domain authentication via the VPN isn't an option, according to our admin.</p>
  
  <p><strong>EDIT</strong>: If there's a way to pass login info to Explorer via the command line, that would be even easier using Ruby and highline.</p>
  
  <p><strong>EDIT</strong>: In case anyone else has the same problem, here's the solution I wound up using. It requires Ruby and the Highline gem.</p>
  
  <pre><code>require "highline/import"
  
  domain = ask("Domain: ")
  username = ask("Username: ")
  password = ask("Password: ") { |q| q.echo = false }
  
  machines = [
      '\\MACHINE1\SHARE', 
      '\\MACHINE2\SHARE', 
      '\\MACHINE3\SHARE', 
      '\\MACHINE4\SHARE', 
      '\\MACHINE5\SHARE'
  ]
  drives = ('f'..'z').to_a[-machines.length..-1]
  
  drives.each{|d| system("net use #{d}: /delete &gt;nul 2&gt;nul"); }
  
  machines.zip(drives).each{|machine, drive| system("net use #{drive}: #{machine} #{password} /user:#{domain}\\#{username} &gt;nul 2&gt;nul")}
  </code></pre>
  
  <p>It'll figure out how many mapped drives I need, then start mapping them to the requested shares. In this case, it maps them from V: to Z:, and assumes I don't have anything shared with those drive letters.</p>
  
  <p>If you already have an Explorer window open to one of the shares, it may give an error, so before I ran the Ruby script, I ran:</p>
  
  <pre><code>net use * /delete
  </code></pre>
  
  <p>That cleared up the "multiple connections to a share not permitted" error, and allowed me to connect with no problems.</p>