Проверьте MaxPasswordAge в Windows с локальным приложением C#
У меня самое плохое время, когда я пытаюсь найти документацию об этом в Интернете. По сути, я хочу знать, что для Secpol MaXPWAge установлено значение 90 или меньше, и он отображается в текстовом поле (для простоты назовем его textbox1). Я искал решение WMI, реестр, GPEDIT в аудиторе и ничего не нашел. Я нашел это, но, честно говоря, я понятия не имею, как использовать один и тот же код для проверки максимального срока действия пароля вместо требований сложности. ПОЖАЛУЙСТА, кто-нибудь может показать мне, что я должен делать здесь? C# не мой основной язык.
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; }
}
}
2 ответа
Это своего рода обман, но он работает, если вы ищете только одну вещь. По сути, он запускает новый процесс и работает net accounts
, затем отпугивает Maximum password age
поле из вывода. Попробуйте, но вам, возможно, придется запустить его от имени администратора:
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;
Я бы написал IniFile
класс как это:
class IniFile : Dictionary<string,Dictionary<string,string>> {
public IniFile(string filename) {
var currentSection = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Add("", currentSection);
foreach (var line in File.ReadAllLines(filename)) {
var trimedLine = line.Trim();
switch (line[0]) {
case ';':
continue;
case '[':
currentSection = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Add(trimedLine.Substring(1, trimedLine.Length - 2), currentSection);
break;
default:
var parts = trimedLine.Split('=');
if (parts.Length > 1) {
currentSection.Add(parts[0].Trim(), parts[1].Trim());
}
break;
}
}
}
public string this[string sectionName, string key] {
get {
Dictionary<string, string> section;
if (!TryGetValue(sectionName, out section)) { return null; }
string value;
if (!section.TryGetValue(key, out value)) { return null; }
return value;
}
}
public int? GetInt(string sectionName, string key) {
string stringValue = this[sectionName, key];
int result;
if (!int.TryParse(stringValue, out result)) { return null; }
return result;
}
}
и поместите генерацию INI-файла в отдельный метод:
class Program {
static void GenerateSecEditOutput(out string tempFile) {
tempFile = Path.GetTempFileName();
var p = new Process {
StartInfo = new ProcessStartInfo {
FileName = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\system32\secedit.exe"),
Arguments = String.Format(@"/export /cfg ""{0}"" /quiet", tempFile),
CreateNoWindow = true,
UseShellExecute = false
}
};
p.Start();
p.WaitForExit();
}
//... Main goes here
}
Затем Main
Метод выглядит так:
static void Main(string[] args) {
//This will be the path of the temporary file which contains the output of secedit.exe
string tempFile;
//Write the output of secedit.exe to the temporary file
GenerateSecEditOutput(out tempFile);
//Parse the temporary file
var iniFile = new IniFile(tempFile);
//Read the maximum password age from the "System Access" section
var maxPasswordAge = iniFile.GetInt("System Access", "MaximumPasswordAge");
if (maxPasswordAge.HasValue) {
Console.WriteLine("MaxPasswordAge = {0}", maxPasswordAge);
} else {
Console.WriteLine("Unable to find MaximumPasswordAge");
}
Console.ReadKey(true);
}
Если у вас есть текстовое поле, в которое вы хотите поместить значение, шаги более или менее одинаковы. Мы можем избежать целочисленного анализа и использовать индексатор IniFile
:
string tempFile;
GenerateSecEditOutput(out tempFile);
var iniFile = new IniFile(tempFile);
//assuming tb is a variable referring to a textbox
tb.Text = iniFile["System Access", "MaximumPasswordAge"];
Имейте в виду, что secedit.exe
требует прав администратора для запуска. Без прав администратора код не будет работать; временный файл будет просто пустым. Смотрите здесь для некоторых предложений о том, как это сделать.