Skip to content

Instantly share code, notes, and snippets.

@pcrama
Last active January 18, 2022 14:28
Show Gist options
  • Save pcrama/a0480922ba7e4a0082c50a97335011f0 to your computer and use it in GitHub Desktop.
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
// .\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