I am having the worst time trying to find documentation of this on the internet. Essentially I want to know that Secpol MaXPWAge is set to 90 or less and have it display in a textbox (let's call it textbox1 for ease) I have searched WMI solution, registry, GPEDIT in auditor and have found nothing. I did find this, but honestly, I have no clue how to use the same code to check the Max Password Age instead of complexity requirements. PLEASE, can someone show me what I should be doing here? C# is not my primary language.
https://gist.github.com/jkingry/421802
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main(string[] args)
{
Console.Write(PasswordComplexityPolicy());
}
static bool PasswordComplexityPolicy()
{
var tempFile = Path.GetTempFileName();
Process p = new Process();
p.StartInfo.FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\secedit.exe");
p.StartInfo.Arguments = String.Format(@"/export /cfg ""{0}"" /quiet", tempFile);
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.WaitForExit();
var file = IniFile.Load(tempFile);
IniSection systemAccess = null;
var passwordComplexityString = "";
var passwordComplexity = 0;
return file.Sections.TryGetValue("System Access", out systemAccess)
&& systemAccess.TryGetValue("PasswordComplexity", out passwordComplexityString)
&& Int32.TryParse(passwordComplexityString, out passwordComplexity)
&& passwordComplexity == 1;
}
class IniFile
{
public static IniFile Load(string filename)
{
var result = new IniFile();
result.Sections = new Dictionary<string, IniSection>();
var section = new IniSection(String.Empty);
result.Sections.Add(section.Name, section);
foreach (var line in File.ReadAllLines(filename))
{
var trimedLine = line.Trim();
switch (line[0])
{
case ';':
continue;
case '[':
section = new IniSection(trimedLine.Substring(1, trimedLine.Length - 2));
result.Sections.Add(section.Name, section);
break;
default:
var parts = trimedLine.Split('=');
if(parts.Length > 1)
{
section.Add(parts[0].Trim(), parts[1].Trim());
}
break;
}
}
return result;
}
public IDictionary<string, IniSection> Sections { get; private set; }
}
class IniSection : Dictionary<string, string>
{
public IniSection(string name) : base(StringComparer.OrdinalIgnoreCase)
{
this.Name = name;
}
public string Name { get; private set; }
}
}
This is kind of a cheat, but it works if you're only looking for that one thing. Basically it starts a new process and runs net accounts
, then scapes the Maximum password age
field from the output. Try it out, but you might have to run it as an administrator:
var process = new Process
{
StartInfo = new ProcessStartInfo()
{
FileName = "net",
Arguments = "accounts",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
}
};
process.Start();
string text = "";
while (!process.StandardOutput.EndOfStream)
{
text = process.StandardOutput.ReadLine();
if (text != null && text.StartsWith("Maximum password age (days):"))
break;
}
if (text == null || !text.StartsWith("Maximum password age (days):"))
return;
text = text.Replace("Maximum password age (days):", "").Trim();
textBox1.Text = text;