質問する質問する
 

回答済みVB.net or C# - Query Exchange 2010 informations

  • 2009年11月23日 9:51jravn ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     

    Hello

    The code (VB 2008) below is working when it's executed local on the exchange 2010 server

    Dim rsConfig As RunspaceConfiguration = RunspaceConfiguration.Create()
    Dim snapInException As PSSnapInException = Nothing
    Dim info As PSSnapInInfo = rsConfig.AddPSSnapIn("Microsoft.Exchange.Management.PowerShell.E2010", snapInException)

    Dim myRunSpace As Runspace = RunspaceFactory.CreateRunspace(rsConfig)
    Dim pipeLine As Pipeline = myRunSpace.CreatePipeline()
    Dim ri As New RunspaceInvoke(myRunSpace)´

    myRunSpace.Open()

    Dim commandResults As Collection(Of PSObject)
    commandResults = ri.Invoke("Get-Recipient -ResultSize unlimited")

    When i try to execute the same code from a Windows 7 x64 + ESM 2010, it give me a unhandled exception with the error code below.
    "The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security"

    I have read the link below, but im having a hard time to fit that sample code into my code logic.
    http://msexchangeteam.com/archive/2009/11/02/453016.aspx

    Is there anyone who is having a "remote execution sample" without hardcoded username and password, for the exchange 2010 platform.

    Thanks,

    /Jesper

回答

  • 2009年11月25日 8:17jravn ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     回答済み
    Hello

    Dave Vespa sent me a code sample which solves my problem. Thanks Dave!.
    Case closed :-).

    if (userName.Length > 0 && password.Length > 0)
                {
                    System.Security.SecureString securePassword = new System.Security.SecureString();

                    foreach (char c in password.ToCharArray())
                    {
                        securePassword.AppendChar(c);
                    }

                    creds = new System.Management.Automation.PSCredential(userName, securePassword);
                }
                else
                {
                    // This is to handle the use Windows Integrated AuthN case.
                    creds = (PSCredential)null;
                }
                
                RunspaceConfiguration rc = RunspaceConfiguration.Create();
                WSManConnectionInfo wsManInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);

    /Jesper

    • 回答としてマークjravn 2009年11月25日 8:18
    •  

すべての返信

  • 2009年11月23日 13:38Laeeq Qazi ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     回答の候補
    Hi,

          I havent installed Ex2010 in my lab yet, but I m sure that old way of executing PS Cmdlets will not work for Ex2010 becoz  now Powershell is run in a Remote envrionment. 

          Please see this article which explains how to run PS Cmdlets in Ex2010 in a Remote enivronment.

          http://msexchangeteam.com/archive/2009/11/02/453016.aspx (Programmatic Access via Remote PowerShell in Exchange Server 2010)

         You will have to modify your code which creates PS Snapin and Pipeline object.

       Regards,

    Laeeq Qazi|Snr Software Engineer(Exchange + Sharepoint + BES + DynamicsCRM) www.HostingController.com
    • 回答の候補に設定Laeeq Qazi 2009年11月23日 13:39
    •  
  • 2009年11月23日 19:48jravn ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     
    Hi Laeeq

    Thanks for your feedback. 
    Yes you are correct about the remote execution. My problem is, that Im not able to get the sample code working, provided by the exchange team.
    I have tried to convert the sample code to VB.net. Please see the code below.

     Dim runspace As Runspace = System.Management.Automation.Runspaces.RunspaceFactory.CreateRunspace()
            Dim powershell As PowerShell = powershell.Create()
            Dim command As New PSCommand()
            command.AddCommand("New-PSSession")
            command.AddParameter("ConfigurationName", "Microsoft.Exchange")
            command.AddParameter("ConnectionUri", New Uri(liveIdconnectionUri))
            command.AddParameter("Credential", cred)
            command.AddParameter("Authentication", "Basic")
            powershell.Commands = command

            ' open the remote runspace
            runspace.Open()
            ' associate the runspace with powershell
            powershell.Runspace = runspace
            ' invoke the powershell to obtain the results
            'Dim result As Collection(Of RemoteRunspaceInfo) = powershell.Invoke(Of RemoteRunspaceInfo)()
            Dim result As Collection(Of RemoteRunspaceInfo) = powershell.Invoke(Of RemoteRunspaceInfo)()
            For Each current As ErrorRecord In powershell.Streams.[Error]
                ' Console.WriteLine(("The following Error happen when opening the remote Runspace: " & current.Exception.ToString() & " | InnerException: ") + current.Exception.InnerException)
            Next
            If result.Count <> 1 Then
                Throw New Exception("Unexpected number of Remote Runspace connections returned.")
            End If
            ' Set the runspace as a local variable on the runspace
            powershell = powershell.Create()
            command = New PSCommand()
            command.AddCommand("Set-Variable")
            command.AddParameter("Name", "ra")
            command.AddParameter("Value", result(0))
            powershell.Commands = command
            powershell.Runspace = runspace
            powershell.Invoke()

            powershell = powershell.Create()
            command = New PSCommand()
            command.AddScript("Invoke-Command -ScriptBlock { Get-Mailbox -Identity:" & mailboxName & " } - Session $ra")
            powershell.Commands = command
            powershell.Runspace = runspace
            'Return powershell.Invoke()

            ' dispose the runspace and enable garbage collection
            runspace.Dispose()
            runspace = Nothing
            ' Finally dispose the powershell and set all variables to null to free
            ' up any resources.
            powershell.Dispose()
            powershell = Nothing

    But VB.net does not understand the code lines below.
    command.AddParameter("ConnectionUri", New Uri(liveIdconnectionUri))
    command.AddParameter("Credential", cred)
    Dim result As Collection(Of RemoteRunspaceInfo) = powershell.Invoke(Of RemoteRunspaceInfo)()

    Do you or anyone else have some ideers to fix these issues.
    I have search google for a working connection/execution  code sample, without any luck, so i would appreciate it very much, if someone could help me out here.

    Thanks,

    /Jesper



  • 2009年11月24日 19:16jravn ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     
    Hello

    Ok, I found a great sample from Dave Vespa and got it up and running in VB.net.
    http://blogs.msdn.com/dvespa/archive/2009/10/22/how-to-call-exchange-2010-cmdlet-s-using-remote-powershell-in-code.aspx

    My problem is, that i don't want to hardcode any password in my compiled application.
    Is there any other way I can make a remote connection/execution without the hardcoded password. e.g. by using ntlm/kerberos auth.
    Sorry if missing the point about the new remote powershell, but the documentation in this area (C#/VB.net) is really hard to find.

    Thanks,

    /Jesper
  • 2009年11月25日 8:17jravn ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     回答済み
    Hello

    Dave Vespa sent me a code sample which solves my problem. Thanks Dave!.
    Case closed :-).

    if (userName.Length > 0 && password.Length > 0)
                {
                    System.Security.SecureString securePassword = new System.Security.SecureString();

                    foreach (char c in password.ToCharArray())
                    {
                        securePassword.AppendChar(c);
                    }

                    creds = new System.Management.Automation.PSCredential(userName, securePassword);
                }
                else
                {
                    // This is to handle the use Windows Integrated AuthN case.
                    creds = (PSCredential)null;
                }
                
                RunspaceConfiguration rc = RunspaceConfiguration.Create();
                WSManConnectionInfo wsManInfo = new WSManConnectionInfo(serverUri, SHELL_URI, creds);

    /Jesper

    • 回答としてマークjravn 2009年11月25日 8:18
    •  
  • 2009年11月25日 8:21Laeeq Qazi ユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダルユーザーのメダル
     
    Hi,

       In that kind of condition normally you have to devise a way to pass the required password to application. 

       For instance you can encode your password and then put it in some xml or txt file and read that encoded password into your application and then decode it in your application and use as you need. So there is no need to hard code it, even,if your app is not a service and has some GUI, you can ask the user of your application to enter the pwd in some field on GUI. There are various ways.


       Regards,

    Laeeq Qazi|Snr Software Engineer(Exchange + Sharepoint + BES + DynamicsCRM) www.HostingController.com