Skip to content

Commit 58f6abd

Browse files
committed
Version 1.0.0.1
1 parent ae62e3e commit 58f6abd

File tree

23 files changed

+156
-48
lines changed

23 files changed

+156
-48
lines changed

Docs/Job.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ Your PowerCommands application may of course have so other name and your command
1414
"powercommands.exe job argument1"
1515
```
1616

17+
## Run PowerCommand with a service account
18+
If you want to run your PowerCommands application as a Windows scheduled task started by a service accounts that is not allowed to login on the machine, you need to do a couple of steps.
19+
20+
- You need to copy the PainKiller directory from your %User%\AppData\Roaming to the corresponding one for the service account.
21+
- Copy the environment variable _encryptionManager and create the same as a system environment variable. EncryptionService will look for the system environment variable if the user environment variable is not there.
22+
- For your stored secrets you will need to to do the same thing and change target: User to target: Machine in the **PowerCommandsConfiguration.yaml** file.
23+
1724
Read more about:
1825

1926
[Design your Command](Design_command.md)

Templates/PowerCommands.zip

1.13 KB
Binary file not shown.

Templates/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,18 @@
66

77
Copy the .zip file into the user project template directory. By default, this directory is **%USERPROFILE%\Documents\Visual Studio <version>\Templates\ProjectTemplates** (do not place it in any of the subfolders).
88

9-
Open Visual Studio and write Power in the searchbox, you should find the PowerCommand template.
9+
Open Visual Studio and write Power in the searchbox, you should find the PowerCommand template.
10+
11+
12+
# What is new?
13+
14+
## Version 1.0.0.1
15+
**Released 2023-06-12**
16+
### Capability to Run PowerCommand with a service account
17+
If you want to run your PowerCommands application as a Windows scheduled task started by a service accounts that is not allowed to login on the machine, you need to do a couple of steps.
18+
19+
- You need to copy the PainKiller directory from your %User%\AppData\Roaming to the corresponding one for the service account.
20+
- Copy the environment variable _encryptionManager and create the same as a system environment variable. EncryptionService will look for the system environment variable if the user environment variable is not there.
21+
- For your stored secrets you will need to to do the same thing and change target: User to target: Machine in the **PowerCommandsConfiguration.yaml** file.
22+
### Improved logging
23+
Every log post now includes the current user running the PowerCommand application, the Log commands has been re-designed to use suggestions instead of options where more appropriate.

Templates/src/Core/PainKiller.PowerCommands.Configuration/DOMAINOBJECTS/ConfigurationGlobals.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@ public static class ConfigurationGlobals
55
public const string Prompt = "pcm>";
66
public const string MainConfigurationFile = "PowerCommandsConfiguration.yaml";
77
public const string SecurityFileName = "security.yaml";
8+
public const string WhatsNewFileName = "whats_new.md";
9+
810
public static readonly string ApplicationDataFolder = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\{nameof(PowerCommands)}";
911
}

Templates/src/Core/PainKiller.PowerCommands.Configuration/MyTemplate.vstemplate

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="Project">
22
<TemplateData>
33
<Name>PainKiller.PowerCommands.Configuration</Name>
4-
<Description>Power Commands configuration</Description>
4+
<Description>&lt;No description available&gt;</Description>
55
<ProjectType>CSharp</ProjectType>
66
<ProjectSubType>
77
</ProjectSubType>
Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,53 @@
11
namespace $safeprojectname$.Commands;
22

3-
[PowerCommandTest(tests: "--list|--view|--process git")]
3+
[PowerCommandTest(tests: "list|view|--process git")]
44
[PowerCommandDesign( description: "View and manage the log",
5-
options: "view|archive|!process",
5+
options: "!process",
6+
suggestions: "view|archive",
67
disableProxyOutput: true,
7-
example: "//View a list with all the logfiles|log|//Archive the logs into a zip file.|log --archive|//View content of the current log|log --view|//Filter the log show only posts matching the provided process tag, this requires that you are using process tags when logging in your command(s).|log --process created")]
8+
example: "//View a list with all the logfiles|log|//Archive the logs into a zip file.|log archive|//View content of the current log|log view|//Filter the log show only posts matching the provided process tag, this requires that you are using process tags when logging in your command(s).|log --process created")]
89
public class LogCommand : CommandBase<CommandsConfiguration>
910
{
1011
public LogCommand(string identifier, CommandsConfiguration configuration) : base(identifier, configuration) { }
1112

1213
public override RunResult Run()
1314
{
1415
if (Input.Options.Length == 0) List();
15-
if (Input.HasOption("archive")) Archive();
16-
if (Input.HasOption("view")) View();
16+
if (Input.SingleArgument == "archive") Archive();
17+
if (Input.SingleArgument == "view") View();
1718
if (Input.HasOption("process")) ProcessLog($"{Input.GetOptionValue("process")}");
1819

1920
return Ok();
2021
}
2122
private void List()
2223
{
24+
DisableLog();
2325
var dir = new DirectoryInfo(Path.Combine(AppContext.BaseDirectory, Configuration.Log.FilePath));
2426
foreach (var file in dir.GetFiles("*.log").OrderByDescending(f => f.LastWriteTime)) WriteLine($"{file.Name} {file.LastWriteTime}");
2527
Console.WriteLine();
2628
WriteHeadLine("To view current logfile type log view");
27-
WriteHeadLine("Example");
28-
ConsoleService.Service.WriteLine(nameof(LogCommand), "log --view");
29+
WriteCodeExample("log","view");
2930

3031
Console.WriteLine();
31-
WriteHeadLine("To archive the logs into a zip file type log --archive");
32-
WriteHeadLine("Example");
33-
ConsoleService.Service.WriteLine(nameof(LogCommand), "log --archive");
32+
WriteHeadLine("To archive the logs into a zip file type log archive");
33+
WriteCodeExample("log","archive");
34+
35+
Console.WriteLine();
36+
WriteHeadLine("To view a certain process log use:");
37+
WriteCodeExample("log","--process myProcess");
38+
EnableLog();
3439
}
3540
private void Archive() => WriteLine(Configuration.Log.ArchiveLogFiles());
3641
private void View()
3742
{
43+
DisableLog();
3844
foreach (var line in Configuration.Log.ToLines()) ConsoleService.Service.WriteLine(nameof(LogCommand), line);
45+
EnableLog();
3946
}
4047
private void ProcessLog(string processTag)
4148
{
49+
DisableLog();
4250
foreach (var line in Configuration.Log.GetProcessLog(processTag)) ConsoleService.Service.WriteLine(nameof(LogCommand), line);
51+
EnableLog();
4352
}
4453
}

Templates/src/Core/PainKiller.PowerCommands.Core/COMMANDS/VersionCommand.cs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,28 @@ public VersionCommand(string identifier, CommandsConfiguration configuration) :
1111

1212
public override RunResult Run()
1313
{
14-
WriteLine($"{nameof(Core)}: {ReflectionService.Service.GetVersion(Assembly.Load($"$safeprojectname$"))}");
15-
WriteLine($"{nameof(PowerCommands.Configuration)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Configuration"))}");
16-
WriteLine($"{nameof(ReadLine)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.ReadLine"))}");
17-
WriteLine($"{nameof(Security)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Security"))}");
18-
WriteLine($"{nameof(Shared)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Shared"))}");
14+
WriteLine($" {nameof(Core)}: {ReflectionService.Service.GetVersion(Assembly.Load($"$safeprojectname$"))}");
15+
WriteLine($" {nameof(PowerCommands.Configuration)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Configuration"))}");
16+
WriteLine($" {nameof(ReadLine)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.ReadLine"))}");
17+
WriteLine($" {nameof(Security)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Security"))}");
18+
WriteLine($" {nameof(Shared)}: {ReflectionService.Service.GetVersion(Assembly.Load($"PainKiller.PowerCommands.Shared"))}");
19+
20+
var rows = File.ReadAllLines(Path.Combine(AppContext.BaseDirectory, ConfigurationGlobals.WhatsNewFileName));
21+
foreach (var row in rows)
22+
{
23+
var displayRow = row.Replace("#", "").Replace("**", "");
24+
if (row.StartsWith("#"))
25+
{
26+
WriteHeadLine($"\n{displayRow}");
27+
continue;
28+
}
29+
if (row.StartsWith("*"))
30+
{
31+
WriteSuccessLine($" {displayRow}");
32+
continue;
33+
}
34+
WriteLine($" {displayRow}");
35+
}
1936
return Ok();
2037
}
2138
}

Templates/src/Core/PainKiller.PowerCommands.Core/PainKiller.PowerCommands.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<LangVersion>10.0</LangVersion>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
8+
<Version>1.0.0.1</Version>
89
</PropertyGroup>
910

1011
<ItemGroup>

Templates/src/Core/PainKiller.PowerCommands.Core/SERVICES/EncryptionService.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
namespace $safeprojectname$.Services;
2-
32
public class EncryptionService : IEncryptionService
43
{
4+
private readonly string _sharedSecret;
5+
private readonly string _salt;
56
private EncryptionService()
67
{
78
var securityConfiguration = ConfigurationService.Service.GetAppDataConfiguration<SecurityConfiguration>(ConfigurationGlobals.SecurityFileName).Configuration;
89
_salt = securityConfiguration.Encryption.SharedSecretSalt;
910
_sharedSecret = Environment.GetEnvironmentVariable(securityConfiguration.Encryption.SharedSecretEnvironmentKey, EnvironmentVariableTarget.User) ?? string.Empty;
11+
if(string.IsNullOrEmpty(_sharedSecret)) _sharedSecret = Environment.GetEnvironmentVariable(securityConfiguration.Encryption.SharedSecretEnvironmentKey, EnvironmentVariableTarget.Machine) ?? string.Empty; //Retry if the shared secret has been set as a system environment variable
1012
if (string.IsNullOrEmpty(_sharedSecret)) ConsoleService.Service.WriteWarning(nameof(EncryptionService),$"The environment variable [{securityConfiguration.Encryption.SharedSecretEnvironmentKey}] is missing, you should generate a salt with secret --salt\nAnd then create the environment variable with the salt as value with user scope, before you create secrets (otherwise you need to re-create them again)");
11-
_encryptionManager = new AESEncryptionManager(_salt);
1213
}
13-
1414
private static readonly Lazy<IEncryptionService> Lazy = new(() => new EncryptionService());
1515
public static IEncryptionService Service => Lazy.Value;
1616

17-
private readonly string _sharedSecret;
18-
private readonly string _salt;
19-
private readonly IEncryptionManager _encryptionManager;
2017
public string EncryptString(string plainText)
2118
{
2219
var encryptionManager = new AESEncryptionManager(_salt);

Templates/src/PainKiller.PowerCommands.Bootstrap/MyTemplate.vstemplate

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<ProjectItem ReplaceParameters="true" TargetFileName="PowerCommandsManager.cs">PowerCommandsManager.cs</ProjectItem>
2323
<ProjectItem ReplaceParameters="true" TargetFileName="PowerCommandsManager.partial.cs">PowerCommandsManager.partial.cs</ProjectItem>
2424
<ProjectItem ReplaceParameters="true" TargetFileName="Startup.cs">Startup.cs</ProjectItem>
25+
<ProjectItem ReplaceParameters="false" TargetFileName="whats_new.md">whats_new.md</ProjectItem>
2526
</Project>
2627
</TemplateContent>
2728
</VSTemplate>

0 commit comments

Comments
 (0)