2015-05-28 10 views
1

У меня худшее время, пытаясь найти документацию об этом в Интернете. По сути, я хочу знать, что Secpol MaXPWAge установлен на уровне 90 или меньше и отображает его в текстовом поле (назовем его текстовым полем1 для удобства). Я искал решение WMI, реестр, GPEDIT в аудиторе и ничего не нашел. Я нашел это, но, честно говоря, я не знаю, как использовать тот же код для проверки Max Password Age, а не требований сложности. ПОЖАЛУЙСТА, может кто-нибудь покажет мне, что я должен здесь делать? C# не является моим основным языком.Check MaxPasswordAge в Windows с локальным приложением 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; 
+0

NOPE! никакой доступ администратора не нужен, кажется, что он работает нормально. Это замечательно, спасибо –

+0

@JoePearson - 'net accounts' также можно использовать для установки максимального возраста пароля. Поэтому, если вам нужна эта функциональность, изменить этот код не сложно. – Icemanind

+0

@Icemanmind Есть ли аналогичный метод для определения нашего, если пользователю разрешен срок действия через LUSRMGR.msc? –

0

Я написал бы 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 требует права администратора для запуска. Без прав администратора код не будет работать; временный файл будет просто пустым. См. here для некоторых предложений о том, как это сделать.

+0

shouldnt var si = new be null? он не компилируется, поскольку он стоит сейчас –

+0

@JoePearson Исправлено. Сначала я написал это с головы, так что он все еще не скомпилировался. –

+0

Нет, это скомпилировано просто отлично. Так скажите мне, как я могу получить данные в форме окна. IE. поместите полученные данные в текстовое поле. –

 Смежные вопросы

  • Нет связанных вопросов^_^