本文介绍了运行PowerShell的脚本从C#应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从C#应用程序中执行powershellscript。该脚本以特殊的UserContext执行。

I'm trying to execute a powershellscript from a c# application. The script has to be executed under a special usercontext.

我已经尝试了不同的场景有些工作有些不是:

I've tried different scenarios some are working some not:

1。从PowerShell中直接调用

我叫从中下正确usercredentials运行PS-控制台directely脚本。

I've called the script directely from a ps-console which is running under the correct usercredentials.

C:\Scripts\GroupNewGroup.ps1 1

结果:成功运行脚本

2。从C#控制台应用程序

我叫从中下正确usercredentials开始了C#consoleapplication脚本。

I've called the script from a c# consoleapplication which is started under the correct usercredentials.

code:

 string cmdArg = "C:\\Scripts\\GroupNewGroup.ps1 1"
 Runspace runspace = RunspaceFactory.CreateRunspace();
 runspace.ApartmentState = System.Threading.ApartmentState.STA;
 runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;


     runspace.Open();

 Pipeline pipeline = runspace.CreatePipeline();

 pipeline.Commands.AddScript(cmdArg);
 pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
 Collection<PSObject> results = pipeline.Invoke();
 var error = pipeline.Error.ReadToEnd();
 runspace.Close();

 if (error.Count >= 1)
 {
     string errors = "";
     foreach (var Error in error)
     {
         errors = errors + " " + Error.ToString();
     }
 }

结果:没有成功。和很多空阵的异常。

Result: No Success. And a lot of "Null-Array" exceptions.

3。从C#控制台应用程序 - code面imapersonating

()

我叫从中下正确usercredentials和code包含模拟开始了C#consoleapplication脚本。

I've called the script from a c# consoleapplication which is started under the correct usercredentials and the code contains impersonation.

code:

using (new Impersonator("Administrator2", "domain", "testPW"))

                   {
  using (RunspaceInvoke invoker = new RunspaceInvoke())
{
    invoker.Invoke("Set-ExecutionPolicy Unrestricted");
}

     string cmdArg = "C:\\Scripts\\GroupNewGroup.ps1 1";
     Runspace runspace = RunspaceFactory.CreateRunspace();
     runspace.ApartmentState = System.Threading.ApartmentState.STA;
     runspace.ThreadOptions = PSThreadOptions.UseCurrentThread;


         runspace.Open();

     Pipeline pipeline = runspace.CreatePipeline();

     pipeline.Commands.AddScript(cmdArg);
     pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
     Collection<PSObject> results = pipeline.Invoke();
     var error = pipeline.Error.ReadToEnd();
     runspace.Close();

     if (error.Count >= 1)
     {
         string errors = "";
         foreach (var Error in error)
         {
             errors = errors + " " + Error.ToString();
         }
     }
 }

结果:


  • 术语GET-联系未被识别为cmdlet的名字,
    函数,脚本文件或可操作的程序。检查的拼写
    名称,或者是否包含路径,验证路径是正确的,
    再试一次。

  • 术语C:\\脚本\\ FunctionsObjects.ps1'无法识别的
    命名cmdlet,函数,脚本文件或可操作的程序的。检查
    名字的拼写,或者是否包含路径,验证
    路径是否正确,然后重试。

  • 没有管理单元已注册的Windows PowerShell版本2。
    Microsoft.Office.Server,版本= 14.0.0.0,文化=中立,
    公钥= 71e9bce111e9429c

  • System.DirectoryServices.AccountManagement,版本= 4.0.0.0,
    文化=中性公钥= b77a5c561934e089

  • 异常调用.ctor和1的说法(S):Web应用程序
    的http:// XXXX /网站/ TEST4 / 找不到。确认您
    正确输入了网址。如果URL应该提供现有
    内容时,系统管理员可能需要添加一个新的请求URL
    映射到预期的应用。

  • 您不能调用一个空值前pression的方法。不能索引
    成空数组。

  • The term 'Get-Contact' is not recognized as the name of a cmdlet,function, script file, or operable program. Check the spelling of thename, or if a path was included, verify that the path is correct andtry again.
  • The term 'C:\Scripts\FunctionsObjects.ps1' is not recognized as thename of a cmdlet, function, script file, or operable program. Checkthe spelling of the name, or if a path was included, verify that thepath is correct and try again.
  • No snap-ins have been registered for Windows PowerShell version 2.Microsoft.Office.Server, Version=14.0.0.0, Culture=neutral,PublicKeyToken=71e9bce111e9429c
  • System.DirectoryServices.AccountManagement, Version=4.0.0.0,Culture=neutral, PublicKeyToken=b77a5c561934e089
  • Exception calling ".ctor" with "1" argument(s): "The Web applicationat http://XXXX/websites/Test4/ could not be found. Verify that youhave typed the URL correctly. If the URL should be serving existingcontent, the system administrator may need to add a new request URLmapping to the intended application."
  • You cannot call a method on a null-valued expression. Cannot indexinto a null array.

到现在为止也没有工作答案

有谁知道为什么有差异,如何解决这个问题?

Does anyone know why there are differences and how to solve the problem?

推荐答案

你试过设置ExecutionPolicy不受限制

using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
    using (RunspaceInvoke invoker = new RunspaceInvoke())
    {
        invoker.Invoke("Set-ExecutionPolicy Unrestricted");
    }
}

编辑:

找到这个小宝石...的

Found this little gem... http://www.codeproject.com/Articles/10090/A-small-C-Class-for-impersonating-a-User

namespace Tools
{
    #region Using directives.
    // ----------------------------------------------------------------------

    using System;
    using System.Security.Principal;
    using System.Runtime.InteropServices;
    using System.ComponentModel;

    // ----------------------------------------------------------------------
    #endregion

    /////////////////////////////////////////////////////////////////////////

    /// <summary>
    /// Impersonation of a user. Allows to execute code under another
    /// user context.
    /// Please note that the account that instantiates the Impersonator class
    /// needs to have the 'Act as part of operating system' privilege set.
    /// </summary>
    /// <remarks>
    /// This class is based on the information in the Microsoft knowledge base
    /// article http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306158
    ///
    /// Encapsulate an instance into a using-directive like e.g.:
    ///
    ///     ...
    ///     using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
    ///     {
    ///         ...
    ///         [code that executes under the new context]
    ///         ...
    ///     }
    ///     ...
    ///
    /// Please contact the author Uwe Keim (mailto:uwe.keim@zeta-software.de)
    /// for questions regarding this class.
    /// </remarks>
    public class Impersonator :
        IDisposable
    {
        #region Public methods.
        // ------------------------------------------------------------------

        /// <summary>
        /// Constructor. Starts the impersonation with the given credentials.
        /// Please note that the account that instantiates the Impersonator class
        /// needs to have the 'Act as part of operating system' privilege set.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        public Impersonator(
            string userName,
            string domainName,
            string password )
        {
            ImpersonateValidUser( userName, domainName, password );
        }

        // ------------------------------------------------------------------
        #endregion

        #region IDisposable member.
        // ------------------------------------------------------------------

        public void Dispose()
        {
            UndoImpersonation();
        }

        // ------------------------------------------------------------------
        #endregion

        #region P/Invoke.
        // ------------------------------------------------------------------

        [DllImport("advapi32.dll", SetLastError=true)]
        private static extern int LogonUser(
            string lpszUserName,
            string lpszDomain,
            string lpszPassword,
            int dwLogonType,
            int dwLogonProvider,
            ref IntPtr phToken);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        private static extern int DuplicateToken(
            IntPtr hToken,
            int impersonationLevel,
            ref IntPtr hNewToken);

        [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
        private static extern bool RevertToSelf();

        [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
        private static extern  bool CloseHandle(
            IntPtr handle);

        private const int LOGON32_LOGON_INTERACTIVE = 2;
        private const int LOGON32_PROVIDER_DEFAULT = 0;

        // ------------------------------------------------------------------
        #endregion

        #region Private member.
        // ------------------------------------------------------------------

        /// <summary>
        /// Does the actual impersonation.
        /// </summary>
        /// <param name="userName">The name of the user to act as.</param>
        /// <param name="domainName">The domain name of the user to act as.</param>
        /// <param name="password">The password of the user to act as.</param>
        private void ImpersonateValidUser(
            string userName,
            string domain,
            string password )
        {
            WindowsIdentity tempWindowsIdentity = null;
            IntPtr token = IntPtr.Zero;
            IntPtr tokenDuplicate = IntPtr.Zero;

            try
            {
                if ( RevertToSelf() )
                {
                    if ( LogonUser(
                        userName,
                        domain,
                        password,
                        LOGON32_LOGON_INTERACTIVE,
                        LOGON32_PROVIDER_DEFAULT,
                        ref token ) != 0 )
                    {
                        if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
                        {
                            tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
                            impersonationContext = tempWindowsIdentity.Impersonate();
                        }
                        else
                        {
                            throw new Win32Exception( Marshal.GetLastWin32Error() );
                        }
                    }
                    else
                    {
                        throw new Win32Exception( Marshal.GetLastWin32Error() );
                    }
                }
                else
                {
                    throw new Win32Exception( Marshal.GetLastWin32Error() );
                }
            }
            finally
            {
                if ( token!= IntPtr.Zero )
                {
                    CloseHandle( token );
                }
                if ( tokenDuplicate!=IntPtr.Zero )
                {
                    CloseHandle( tokenDuplicate );
                }
            }
        }

        /// <summary>
        /// Reverts the impersonation.
        /// </summary>
        private void UndoImpersonation()
        {
            if ( impersonationContext!=null )
            {
                impersonationContext.Undo();
            }
        }

        private WindowsImpersonationContext impersonationContext = null;

        // ------------------------------------------------------------------
        #endregion
    }

    /////////////////////////////////////////////////////////////////////////
}

这篇关于运行PowerShell的脚本从C#应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 14:56
查看更多