Last active
January 18, 2022 14:28
-
-
Save pcrama/a0480922ba7e4a0082c50a97335011f0 to your computer and use it in GitHub Desktop.
Read Windows user name & password from plain text file and execute command with those credentials
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// .\CompileSimply-CSharp.ps1 . RunAsFromFile.cs "64" "System.Diagnostics.Process.dll" | |
// | |
// From https://social.technet.microsoft.com/Forums/lync/en-US/132e170f-e3e8-4178-9454-e37bfccd39ea/startprocess-verb-runas-amp-credential | |
// $pw= convertto-securestring "PASSWORD" -asplaintext –force | |
// $pp = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user",$pw | |
// $script = "c:\pathtoscript.ps1" | |
// Start-Process powershell -Credential $pp -ArgumentList '-noprofile -command &{Start-Process $script -verb runas}' | |
// $pw= convertto-securestring "PASSWORD" -asplaintext –force | |
// $pp = new-object -typename System.Management.Automation.PSCredential -argumentlist "DOMAIN\user",$pw | |
// $script = "c:\pathtoscript.ps1" | |
// Start-Process powershell -Credential $pp -ArgumentList '-noprofile -command &{Start-Process $script -verb runas}' | |
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; // System.Diagnostics.Process.dll | |
using System.Security; | |
namespace runasfromfile | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
if (args.Length > 1) { | |
var commandLine = new ArraySegment<string>(args, 1, args.Length - 1); | |
cat(args[0], | |
(u, p) => { StartProcessAs(commandLine, u, p); }); | |
} else { | |
Console.WriteLine("Please give a file name and a command as arguments"); | |
} | |
} | |
static void SplitUserAndDomain(string fullUserName, out string domain, out string user) | |
{ | |
var defaultDomain = System.Environment.MachineName; | |
var parts = fullUserName.Split('\\'); | |
if (1 == parts.Length) | |
{ | |
domain = defaultDomain; | |
user = fullUserName; | |
} | |
else if ("." == parts[0]) | |
{ | |
domain = defaultDomain; | |
user = parts[1]; | |
} | |
else | |
{ | |
domain = parts[0]; | |
user = parts[1]; | |
} | |
} | |
static void StartProcessAs(ArraySegment<string> cmdLine, string fullUserName, string password) | |
{ | |
var startInfo = new ProcessStartInfo(); | |
startInfo.UseShellExecute = false; | |
startInfo.FileName = cmdLine.Array[cmdLine.Offset]; | |
startInfo.Arguments = String.Join(" ", cmdLine.Array, cmdLine.Offset + 1, cmdLine.Count - 1); | |
string domain, user; | |
SplitUserAndDomain(fullUserName, out domain, out user); | |
startInfo.Domain = domain; | |
startInfo.UserName = user; | |
startInfo.PasswordInClearText = password; | |
startInfo.WorkingDirectory = System.IO.Path.GetPathRoot(System.IO.Directory.GetCurrentDirectory()); | |
var proc = Process.Start(startInfo); | |
} | |
static bool MatchHeaderAndNotSet(string line, string header, SetOnce<string> value) | |
{ | |
return (value.NotSet | |
&& line.StartsWith(header, | |
StringComparison.CurrentCultureIgnoreCase)); | |
} | |
static string ButFirst(string x) | |
{ | |
var parts = x.Split(" \t".ToCharArray(), 2); | |
return parts[1].Trim(); | |
} | |
static void cat(string arg, Action<string, string> callWithCredentials) | |
{ | |
const string USERNAME = "username"; | |
const string PASSWORD = "password"; | |
var data = new Dictionary<string, SetOnce<string>>(); | |
data.Add(USERNAME, new SetOnce<string>()); | |
data.Add(PASSWORD, new SetOnce<string>()); | |
using(var file = | |
new System.IO.StreamReader(arg)) { | |
string line; | |
while((line = file.ReadLine()) != null) | |
{ | |
foreach (var item in data) | |
{ | |
if (MatchHeaderAndNotSet(line, item.Key, item.Value)) { | |
item.Value.Set(ButFirst(line)); | |
break; | |
} | |
} | |
} | |
var username = data[USERNAME]; | |
var password = data[PASSWORD]; | |
if (username.IsSet && password.IsSet) { | |
callWithCredentials(username.Value, password.Value); | |
} else if (username.NotSet && password.NotSet) { | |
Console.WriteLine("Neither username nor password found in " + arg); | |
} else if (password.IsSet) { | |
Console.WriteLine("Password found: " + new String('*', password.Value.Length)); | |
} else if (username.IsSet) { | |
Console.WriteLine("Username found: " + username.Value); | |
} else { | |
Console.WriteLine("This case should not occur"); | |
} | |
} | |
} | |
} | |
class SetOnce<T> { | |
public bool NotSet { | |
get { return !IsSet; } | |
private set { IsSet = !value; } | |
} | |
public bool IsSet { get; private set; } | |
public T Value { get; private set; } | |
public SetOnce() | |
{ | |
IsSet = false; | |
Value = default(T); | |
} | |
public SetOnce(T v) | |
{ | |
IsSet = true; | |
Value = v; | |
} | |
public SetOnce<T> Set(T v) | |
{ | |
if (NotSet) | |
{ | |
IsSet = true; | |
Value = v; | |
} | |
return this; | |
} | |
} | |
} | |
// Local Variables: | |
// compile-command: "PowerShell.exe -File CompileSimply-CSharp.ps1 . RunAsFromFile.cs 64 mscorlib.dll" | |
// End: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment