Beispiel #1
0
        /// <summary>
        /// Creates new remote PS session if neccesary, and returns unique session identifier
        /// </summary>
        public string Connect(PSConnection options, out object state)
        {
            var connectionHash = GetConnectionHash(options);

            var sessionStateVars = new Dictionary <string, object>(); // state vars as result from InitConnection

            var newLazy       = new Lazy <object>(() => InitConnection(options, sessionStateVars));
            var lazyFromCache = (Lazy <object>)sessions.AddOrGetExisting(connectionHash, newLazy, runspacePolicy);

            try
            {
                // force lazy initialization
                var connection = (lazyFromCache ?? newLazy).Value;
            }
            catch (Exception)
            {
                sessions.Remove(connectionHash);
                throw;
            }

            var stateDict = ((ConcurrentDictionary <string, object>)sessionState
                             .GetOrAdd(connectionHash, _ => new ConcurrentDictionary <string, object>()));

            stateDict.AddOrUpdate(RefCounterKey, 1, (key, current) => (int)current + 1);

            foreach (var sesVars in sessionStateVars)
            {
                stateDict.TryAdd(sesVars.Key, sesVars.Value);
            }

            string newSession = Guid.NewGuid().ToString();

            sessions.Add(newSession, connectionHash, options.ShortTimeConnection ? shortTimeSessionPolicy : sessionPolicy); // session refers to shared connection

            state = stateDict;
            return(newSession);
        }
Beispiel #2
0
        private object InitConnection(PSConnection options, Dictionary <string, object> sessionStateVars)
        {
            Uri    connectTo = null;
            string hostName  = options.ComputerName;

            if (hostName != null && hostName.IndexOf(':') == -1)
            {
                hostName += ":5985";
            }

            connectTo = new Uri(String.Format("http://{0}/wsman", hostName));

            var user = options.UserName;

            if (!user.Contains("\\"))
            {
                user = "******" + user;
            }

            var connection = new WSManConnectionInfo(connectTo, null, new PSCredential(user, options.Password));

            connection.AuthenticationMechanism = options.Authentication;

            Runspace runspace;

            if (options.InteractiveTerminal)
            {
                var factory         = new PsFactory();
                var interactiveHost = new WmBridge.Web.Terminal.Host(factory);

                if (options.Options != null)
                {
                    dynamic size;
                    if (options.Options.TryGetValue("BufferSize", out size))
                    {
                        interactiveHost.Terminal.BufferSize = new System.Management.Automation.Host.Size(Convert.ToInt32(size.Width), Convert.ToInt32(size.Height));
                    }

                    if (options.Options.TryGetValue("WindowSize", out size))
                    {
                        interactiveHost.Terminal.WindowSize = new System.Management.Automation.Host.Size(Convert.ToInt32(size.Width), Convert.ToInt32(size.Height));
                    }
                }

                runspace         = RunspaceFactory.CreateRunspace(interactiveHost, connection);
                factory.Runspace = runspace;
                sessionStateVars.Add(PSSessionManager.PSHostClientKey, interactiveHost);
            }
            else
            {
                runspace = RunspaceFactory.CreateRunspace(connection);
            }

            logger.InfoFormat("Opening runspace: {0}", runspace.ConnectionInfo.ComputerName);

            try
            {
                runspace.Open();
                logger.InfoFormat("Runspace opened: {0}; InstanceId: {1}", runspace.ConnectionInfo.ComputerName, runspace.InstanceId);
            }
            catch (Exception ex)
            {
                logger.Error(string.Format("Failed to open runspace: {0} - {1}", runspace.ConnectionInfo.ComputerName, ex.Message));
                throw;
            }

            var eap = "";

            using (var ps = PowerShell.Create())
            {
                ps.Runspace = runspace;

                string script = options.InteractiveTerminal ? "" : "$ErrorActionPreference = 'stop';";

                if (!string.IsNullOrEmpty(options.ExecutionPolicy))
                {
                    script += "Set-ExecutionPolicy $args[0] -Scope Process -Force;";
                }

                script += "$PSVersionTable.PSVersion; $ErrorActionPreference;";

                ps.AddScript(script);
                ps.AddArgument(options.ExecutionPolicy);
                var psResult = ps.Invoke();

                if (psResult.Count == 2)
                {
                    sessionStateVars.Add(PSSessionManager.PSVersionKey, psResult[0].BaseObject as Version);
                    eap = psResult[1].ToString();
                }
            }

            if (!string.IsNullOrEmpty(options.Script))
            {
                using (var ps = PowerShell.Create())
                {
                    ps.Runspace = runspace;
                    ps.AddScript($"$ErrorActionPreference = 'stop'; {options.Script}; $ErrorActionPreference = '{eap}';");
                    ps.Invoke();
                }
            }

            if (!string.IsNullOrEmpty(options.ClientVersion))
            {
                Version ver;
                if (Version.TryParse(options.ClientVersion, out ver))
                {
                    sessionStateVars.Add(PSSessionManager.ClientVersionKey, ver);
                }
            }

            return(runspace);
        }
Beispiel #3
0
 string GetConnectionHash(PSConnection connection)
 {
     using (MD5 md5 = MD5.Create())
         return(System.Convert.ToBase64String(md5.ComputeHash(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(connection)))));
 }