title: How to add image to Active Directory user from C# using PowerShell remoting?
body: <p>I'm writing a program in C# that adds a picture to an Active Directory user object (in the ThumbnailPhoto attribute). The program runs on another PC than the Exchange Server 2010. Using PowerShell remoting I'm able to, for example, enable a mailbox for the AD user.</p>
  
  <p>When I execute the following commands in PowerShell (on another PC than the Exchange Server), it works perfectly:</p>
  
  <pre><code>enter-pssession exchange_server_fqdn
  $cred = get-credential          ( domain\administrator , **** )
  $sess = new-pssession -configurationName Microsoft.Exchange -ConnectionUri http://exchange_server_fqdn/PowerShell/ -Authentication Kerberos -Credential $cred
  import-pssession $sess
  Import-RecipientDataProperty -Identity ADusername -Picture -FileData ([Byte[]]$(Get-Content -Path 'C:\\person.jpg' -Encoding Byte -ReadCount 0))
  remove-pssession $sess
  </code></pre>
  
  <p>But I need to execute the commands from C#. The following code runs (no exception is thrown), but the image isn't added to the AD user object:</p>
  
  <pre><code>string username = "xxx";
  string password = "yyy";
  string exchangeServer = "zzz"; // FQDN of Exchange Server 2010
  string liveIdconnectionUri = "http://" + exchangeServer + "/Powershell?serializationLevel=Full";
  
  // credentials
  SecureString passwordSecureString = new SecureString();
  foreach (char c in password) passwordSecureString.AppendChar(c);
  PSCredential credential = new PSCredential(username, passwordSecureString);
  
  WSManConnectionInfo connectionInfo = new WSManConnectionInfo(
      new Uri(liveIdconnectionUri),
      "http://schemas.microsoft.com/powershell/Microsoft.Exchange",
      credential);
  connectionInfo.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
  
  PowerShell powershell = PowerShell.Create();
  Runspace runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace(connectionInfo);
  runspace.Open();
  powershell.Runspace = runspace;
  PSCommand command = new PSCommand();
  
  // Add ThumbnailPhoto attribute to Active Directory user
  // This command works when executed on the Exchange Server 2010 in the Exchange Management Shell,
  // But it doens't work when executed in C#.
  command.AddScript("Import-RecipientDataProperty -Identity ADusername -Picture -FileData ([Byte[]]$(Get-Content -Path 'C:\\person.jpg' -Encoding Byte -ReadCount 0))");
  
  powershell.Commands = command;
  try {
      Collection&lt;PSObject&gt; commandResults = powershell.Invoke&lt;PSObject&gt;();
      foreach (PSObject result in commandResults) Console.WriteLine(result.ToString());
  }
  catch (Exception ex) {
      Console.WriteLine(ex.Message);
  }
  </code></pre>
  
  <p>The only problem in the code is the line with <code>command.AddScript</code>. If I replace that line with, for example, this:</p>
  
  <pre><code>command.AddCommand("Get-Mailbox");
  command.AddParameter("Identity", "ADusername");
  </code></pre>
  
  <p>... then it does work. Enabling a mailbox also works.</p>
  
  <p>How can I execute the command to add an image to an Active Directory user object from C# (using PowerShell remoting)?</p>
  
  <p><strong>Working code based on accepted answer:</strong></p>
  
  <pre><code>DirectoryEntry container = new DirectoryEntry(LDAP_URI + USERS_DIR);
  DirectoryEntry user = container.Children.Add("cn=" + username, "user");
  
  // Set other property's of the user object:
  //// user.Properties ["xxx"].Value = "yyy";
  //// ...
  
  byte [] buffer;
  FileStream fileStream = new FileStream(@"c:\photo.jpg", FileMode.Open, FileAccess.Read);
  
  try {
      int length = (int) fileStream.Length;  // get file length
      buffer = new byte [length];            // create buffer
      int count;                             // actual number of bytes read
      int sum = 0;                           // total number of bytes read
  
      // read until Read method returns 0 (end of the stream has been reached)
      while ((count = fileStream.Read(buffer, sum, length - sum)) &gt; 0)
          sum += count;  // sum is a buffer offset for next reading
  }
  
  finally {
      fileStream.Close();
  }
  
  user.Properties ["thumbnailPhoto"].Value = buffer;
  
  user.CommitChanges();
  </code></pre>