/
Startup.cs
143 lines (121 loc) · 5.27 KB
/
Startup.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Collections;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace PoshCode.PowerShell
{
public class Startup
{
public static IServiceProvider services;
public static ILogger logger;
public static void Main(string[] args)
{
var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddCommandLine(args)
.Build();
services = new ServiceCollection()
.AddLogging()
.AddSingleton<IConfigurationRoot>(config)
.BuildServiceProvider();
// configure console logging
services.GetService<ILoggerFactory>()
.AddConsole(LogLevel.Debug);
logger = services.GetService<ILoggerFactory>().CreateLogger<Startup>();
logger.LogTrace("Starting application");
// do the actual work here
BeginInvoke();
logger.LogTrace("Exiting application");
}
public static void BeginInvoke()
{
var config = services.GetService<IConfigurationRoot>();
var computerName = config.GetValue("ComputerName", "localhost");
var script = config.GetValue("Script", "1..60 | % { \"Received $_ $(Get-Date)\"; Start-Sleep 5 } | Tee ~\\log.txt");
PSCredential credential = GetCredential(config);
logger.LogDebug($"Connecting to {computerName}");
var connection = new WSManConnectionInfo("http", computerName, 5985, "wsman", $"http://schemas.microsoft.com/powershell/PowerShell.6", credential);
connection.IdleTimeout = 30 * 1000 * 60; // thirty minutes
if (!string.IsNullOrWhiteSpace(script))
{
logger.LogDebug($"Create runspace, and run {{{script}}}");
// When given a script, run it
var runspace = RunspaceFactory.CreateRunspace(connection);
runspace.Open();
using (var powershell = System.Management.Automation.PowerShell.Create())
{
powershell.Runspace = runspace;
powershell.AddScript(script);
powershell.BeginInvoke();
Thread.Sleep(250);
runspace.Disconnect();
}
}
else
{
// Without a script, look for existing runspaces
foreach (var runspace in Runspace.GetRunspaces(connection))
{
if (runspace.RunspaceStateInfo.State == RunspaceState.Disconnected)
{
logger.LogDebug($"Connect runspace {runspace.Name} which is {runspace.RunspaceStateInfo.State}");
using (var powershell = runspace.CreateDisconnectedPowerShell())
{
//var powershell = System.Management.Automation.PowerShell.Create();
//powershell.Runspace = runspace;
logger.LogDebug($"Connect PowerShell {powershell.InstanceId} which is {powershell.InvocationStateInfo.State}");
foreach (var result in powershell.Connect())
{
Console.WriteLine(LanguagePrimitives.ConvertTo(result, typeof(string)));
}
}
}
else
{
logger.LogDebug($"Cannot reconnect runspace {runspace.Name} which is {runspace.RunspaceStateInfo.State}");
}
}
}
//ManualResetEvent running = new ManualResetEvent(false);
//using (running)
//{
// ps.InvocationStateChanged += (sender, args) =>
// {
// logger.LogDebug($"InvocationState: {args.InvocationStateInfo.State}");
// if (running != null && args.InvocationStateInfo.State == PSInvocationState.Running)
// {
// running.Set();
// }
// };
// ps.BeginInvoke();
// logger.LogDebug($"WaitOne");
// running.WaitOne();
// Thread.Sleep(500);
// logger.LogDebug($"Disconnect");
// runspace.Disconnect();
//}
//running = null;
}
private static PSCredential GetCredential(IConfigurationRoot config)
{
var username = config.GetValue<string>("UserName");
var secret = config.GetValue<string>("Password");
if(string.IsNullOrEmpty(username) || string.IsNullOrEmpty(secret))
{
return null;
}
var password = new SecureString();
foreach (var ch in secret.ToCharArray())
{
password.AppendChar(ch);
}
return new PSCredential(username, password);
}
}
}