如何使用PowerShell远程处理从C#向Active Directory用户添加图像?

时间:2012-05-24 13:11:00

标签: c# powershell active-directory exchange-server powershell-remoting

我正在用C#编写一个程序,它将图片添加到Active Directory用户对象(在ThumbnailPhoto属性中)。该程序在另一台PC上运行,而不是Exchange Server 2010.使用PowerShell远程处理我可以为AD用户启用邮箱。

当我在PowerShell中执行以下命令时(在除Exchange Server之外的另一台PC上),它完美地运行:

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

但是我需要从C#执行命令。运行以下代码(不抛出异常),但图像未添加到AD用户对象:

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<PSObject> commandResults = powershell.Invoke<PSObject>();
    foreach (PSObject result in commandResults) Console.WriteLine(result.ToString());
}
catch (Exception ex) {
    Console.WriteLine(ex.Message);
}

代码中唯一的问题是command.AddScript行。如果我用例如:

替换该行
command.AddCommand("Get-Mailbox");
command.AddParameter("Identity", "ADusername");

......然后它确实有效。启用邮箱也可以。

如何执行命令将图像从C#添加到Active Directory用户对象(使用PowerShell远程处理)?

基于已接受答案的工作代码:

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)) > 0)
        sum += count;  // sum is a buffer offset for next reading
}

finally {
    fileStream.Close();
}

user.Properties ["thumbnailPhoto"].Value = buffer;

user.CommitChanges();

2 个答案:

答案 0 :(得分:0)

这听起来像是身份验证问题。即使您在Exchange服务器上运行该命令,它实际上是针对Active Directory执行的,并且无法保证它将执行哪个域控制器。这是双跳场景,可以通过在WS-Man远程会话中使用CredSSP来​​解决。

答案 1 :(得分:0)

我会采取不同的方法:

byte[] pictureBytes = //Use a FileStream to read the data

command.AddCommand("Import-RecipientPropertyData");
command.AddParameter("Identity", "fooUser");
command.AddParameter("Picture", "$true");
command.AddParameter("Encoding", "Byte");
command.AddParameter("ReadCount", 0);
command.AddParameter(FileData, pictureBytes);

或者,您可以将图片读入您的pictureBytes并使用ADSI(DirectoryEntry)直接写入thumbnailPhoto属性。只需确保pictureBytes是&lt; = 10KB,因为这是AD中属性的最大值。