Using DiskPart with C#

I’m in the process of writing a little utility for our technicians to create a bootable USB device from an ISO. This will be primarily used with our SCCM OSD Media, DaRT media, and will probably find several other uses in time. In developing this I ran into an issue….we like to completely reformat the disk when media is created; probably not completely necessary but this seems to help minimize the issues we saw.

There are several articles out and about mentioning different COM and WMI interfaces you can use, but they seemed a bit messy to me. My love for diskpart has grown to an extent and therefore decided to leverage it…but how.

I didn’t like the idea of writing a file and then referencing a diskpart “script” using the “/s” command so I continued my experiment. For those of you who always use the interactive DiskPart console, you can list all your commands into a txt file and then specify this into the command line of a diskpart script.

For example:

<contents of diskpart.txt>

   select disk 1
   clean
   create partition primary
   select partition 1
   format fs=nfts quick
   active
   assign
   exit

I can then use this file on the command line as so:

> diskpart.exe /s diskpart.txt

and all my commands run as if i typed them individually in the diskpart console.

With Powershell, I can use a here-string for this and then pipe the string to diskpart:

$diskpartString = @"
     select disk 1
     clean
     create partition primary
     select partition 1
     format fs=nfts quick
     active
     assign
     exit
   "@

$diskpartString | diskpart

With C# I’m using a method to do this that mimics the same way using an instance of the Process Class:

 

using System.Diagnostics;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      Process p = new Process();                                    // new instance of Process class
      p.StartInfo.UseShellExecute = false;                          // do not start a new shell
      p.StartInfo.RedirectStandardOutput = true;                    // Redirects the on screen results
      p.StartInfo.FileName = @"C:\Windows\System32\diskpart.exe";   // executable to run
      p.StartInfo.RedirectStandardInput = true;                     // Redirects the input commands
      p.Start();                                                    // Starts the process
      p.StandardInput.WriteLine("select disk 2");                   // Issues commands to diskpart
      p.StandardInput.WriteLine("clean");                           //   |
      p.StandardInput.WriteLine("create partition primary");        //   |
      p.StandardInput.WriteLine("select partition 1");              //   |
      p.StandardInput.WriteLine("format fs=fat32 quick");           //   |
      p.StandardInput.WriteLine("active");                          //   |
      p.StandardInput.WriteLine("assign");                          //   |
      p.StandardInput.WriteLine("exit");                            // _\|/_
      string output = p.StandardOutput.ReadToEnd();                 // Places the output to a variable
      p.WaitForExit();                                              // Waits for the exe to finish

      Console.WriteLine(output);                                    // prints the output
    }
  }
}

While this is merely one way of doing this, I like it because it’s self contained and doesn’t require any additional files or api calls. Having the diskpart executable is required. Luckily here, we bake this into our OS Images so we are safe! Perhaps the “dirtiest” part of this is the fact that if we want to pull information from this output, it gets messy. In my instance I just need the volume letter assigned which I’m pulling from WMI.

I’ve instituted a class library to handle most of DiskPart’s commands in this way. Once it has matured a bit i’ll post this back here.

Hopefully, this helps someone somewhere do this!

Enjoi!

Advertisements