如何使用PowerShell远程处理从C#向Active Directory用户添加映像?
我正在用C编写一个程序,将图片添加到Active Directory用户对象(在ThumbnailPhoto属性中)。该程序在Exchange Server 2010以外的其他PC上运行。例如,使用PowerShell远程处理,我能够为AD用户启用邮箱 当我在PowerShell中(在Exchange服务器以外的另一台PC上)执行以下命令时,它工作正常:如何使用PowerShell远程处理从C#向Active Directory用户添加映像?,c#,powershell,active-directory,exchange-server,powershell-remoting,C#,Powershell,Active Directory,Exchange Server,Powershell Remoting,我正在用C编写一个程序,将图片添加到Active Directory用户对象(在ThumbnailPhoto属性中)。该程序在Exchange Server 2010以外的其他PC上运行。例如,使用PowerShell远程处理,我能够为AD用户启用邮箱 当我在PowerShell中(在Exchange服务器以外的另一台PC上)执行以下命令时,它工作正常: enter-pssession exchange_server_fqdn $cred = get-credential (
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);
}
。。。然后它就起作用了。启用邮箱也可以
如何执行命令从C#(使用PowerShell远程处理)向Active Directory用户对象添加映像
基于公认答案的工作代码:
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();
这听起来像是身份验证问题。即使您在Exchange服务器上运行该命令,它实际上是针对Active Directory执行的,并且无法保证它将针对哪个域控制器执行。这是双跳场景,可以通过在WS-Man远程处理会话中使用CredSSP来解决。这听起来像是身份验证问题。即使您在Exchange服务器上运行该命令,它实际上是针对Active Directory执行的,并且无法保证它将针对哪个域控制器执行。这是双跳场景,可以通过在WS-Man远程处理会话中使用CredSSP来解决。我将采用不同的方法:
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
是我就会采取不同的方法:
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
是否确定?因为当我直接在PowerShell中执行该命令时,它可以工作。我的猜测是它与.addScript()
有关。我认为Exchange服务器和域控制器在同一台计算机上,但我不确定这一点。是的,当您直接在PowerShell中执行它时,不存在“双跳”情况。相反,当您使用PowerShell远程处理时,会引入我前面提到的双跳场景。你确定吗?因为当我直接在PowerShell中执行该命令时,它可以工作。我的猜测是它与.addScript()
有关。我认为Exchange服务器和域控制器在同一台计算机上,但我不确定这一点。是的,当您直接在PowerShell中执行它时,不存在“双跳”情况。相反,当您使用PowerShell远程处理时,会引入我前面提到的双跳场景FileStream
与ADSI的结合成功了!有关代码,请参见我的问题。FileStream
与ADSI的结合成功了!请参阅我的问题,了解代码。有没有可以使用的完整源代码?有没有可以使用的完整源代码?