Run PowerShell-Script from C# Application

后端 未结 3 1929
既然无缘
既然无缘 2020-12-05 08:18

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

I\'ve tried different scenarios some are

相关标签:
3条回答
  • 2020-12-05 08:28

    Have you tried Set-ExecutionPolicy Unrestricted

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

    Edit:

    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
        }
    
        /////////////////////////////////////////////////////////////////////////
    }
    
    0 讨论(0)
  • 2020-12-05 08:35

    Several PowerShell cmddlets take a PSCredential object to run using a particular user account. May have a look at this article - http://letitknow.wordpress.com/2011/06/20/run-powershell-script-using-another-account/

    Here's how you can create the Credential object containing the username and password you want to use:

    $username = 'domain\user'
    $password = 'something'
    $cred = New-Object System.Management.Automation.PSCredential -ArgumentList @($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
    

    Once you have the password ready for use in a credential object, you can do a number of things, such as call Start-Process to launch PowerShell.exe, specifying the credential in the -Credential parameter, or Invoke-Command to invoke a "remote" command locally, specifying the credential in the -Credential parameter, or you could call Start-Job to do the work as a background job, passing the credentials you want into the -Credential parameter.

    See here , here & in msdn for more information

    0 讨论(0)
  • 2020-12-05 08:43

    I just spent the day fixing this for myself.

    I finally was able to make it work by adding -Scope Process to Set-ExecutionPolicy

    invoker.Invoke("Set-ExecutionPolicy Unrestricted -Scope Process"); 
    
    0 讨论(0)
提交回复
热议问题