You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于计算机名在C#中生成安全本地管理员密码

Alright, let's tackle this problem head-on. You need a deterministic way to generate 8-12 character local admin passwords from computer names, build a simple UI for this, and reuse the same logic via a DLL in PowerShell to set passwords across workstations. Here's a step-by-step solution that fits your .NET Core 2.0 (or Framework) needs:

1. Core Password Generation Logic (Deterministic & Usable)

The key here is to take a computer name, generate a secure hash, then convert that hash into a human-usable password (no unprintable characters, meets length/complexity rules). We'll use HMACSHA256 with a secret key to ensure the same computer name always produces the same password, while adding a layer of security against brute-force attacks.

using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

public class PasswordGenerator
{
    // Store this secret key securely (e.g., Azure Key Vault, encrypted config)
    private static readonly byte[] _secretKey = Encoding.UTF8.GetBytes("YourOrgSecureSecretKey123!");

    public static string GeneratePassword(string computerName, int minLength = 8, int maxLength = 12)
    {
        if (string.IsNullOrWhiteSpace(computerName))
            throw new ArgumentNullException(nameof(computerName));
        if (minLength < 8 || maxLength > 12 || minLength > maxLength)
            throw new ArgumentOutOfRangeException(nameof(minLength), "Password length must be 8-12 characters");

        // Normalize computer name to lowercase for consistency
        var inputBytes = Encoding.UTF8.GetBytes(computerName.ToLowerInvariant());
        
        using (var hmac = new HMACSHA256(_secretKey))
        {
            var hashBytes = hmac.ComputeHash(inputBytes);
            // Convert hash to Base64 (avoids unprintable bytes)
            var base64Hash = Convert.ToBase64String(hashBytes);
            // Replace Base64 chars that are problematic for passwords
            var sanitizedHash = base64Hash.Replace("+", "x").Replace("/", "y").Replace("=", "z");
            // Pick a random length between min/max (deterministic random based on computer name)
            var passwordLength = new Random(computerName.GetHashCode()).Next(minLength, maxLength + 1);
            var rawPassword = sanitizedHash.Substring(0, passwordLength);
            
            // Ensure password meets common complexity rules (adjust to match your org's policy)
            return EnsureComplexity(rawPassword);
        }
    }

    private static string EnsureComplexity(string password)
    {
        var chars = password.ToCharArray();
        var random = new Random(password.GetHashCode()); // Deterministic random seed
        
        // Add uppercase if missing
        if (!chars.Any(char.IsUpper))
        {
            var idx = random.Next(chars.Length);
            chars[idx] = char.ToUpper(chars[idx]);
        }
        
        // Add digit if missing
        if (!chars.Any(char.IsDigit))
        {
            var idx = random.Next(chars.Length);
            chars[idx] = (char)random.Next('0', '9' + 1);
        }
        
        // Add special character if missing
        var specialChars = new[] { '!', '@', '#', '$', '%', '^', '&', '*' };
        if (!chars.Any(c => specialChars.Contains(c)))
        {
            var idx = random.Next(chars.Length);
            chars[idx] = specialChars[random.Next(specialChars.Length)];
        }
        
        return new string(chars);
    }
}
2. Build a Reusable DLL

To share this logic between your UI and PowerShell, package it as a .NET Standard 2.0 class library (compatible with .NET Core 2.0 and .NET Framework 4.6.1+):

  • Create a new "Class Library (.NET Standard)" project in Visual Studio
  • Add the PasswordGenerator class above
  • Compile to generate your DLL (e.g., OrgPasswordGenerator.dll)
3. Simple UI for Password Generation

Build a lightweight WinForms UI to input computer names and view generated passwords. Reference your DLL in the WinForms project:

using System;
using System.Windows.Forms;

namespace PasswordGeneratorUI
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txtComputerName.Text))
            {
                MessageBox.Show("Please enter a computer name.", "Input Required", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            try
            {
                var password = PasswordGenerator.GeneratePassword(txtComputerName.Text);
                txtPassword.Text = password;
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Error generating password: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // Auto-generated form initialization (add via Visual Studio designer)
        private void InitializeComponent()
        {
            this.txtComputerName = new System.Windows.Forms.TextBox();
            this.btnGenerate = new System.Windows.Forms.Button();
            this.txtPassword = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            
            // txtComputerName
            this.txtComputerName.Location = new System.Drawing.Point(12, 35);
            this.txtComputerName.Size = new System.Drawing.Size(220, 23);
            
            // btnGenerate
            this.btnGenerate.Location = new System.Drawing.Point(238, 35);
            this.btnGenerate.Size = new System.Drawing.Size(120, 23);
            this.btnGenerate.Text = "Generate Password";
            this.btnGenerate.Click += new System.EventHandler(this.btnGenerate_Click);
            
            // txtPassword
            this.txtPassword.Location = new System.Drawing.Point(12, 85);
            this.txtPassword.ReadOnly = true;
            this.txtPassword.Size = new System.Drawing.Size(346, 23);
            
            // Labels
            this.label1.Text = "Computer Name:";
            this.label1.Location = new System.Drawing.Point(12, 15);
            this.label2.Text = "Generated Password:";
            this.label2.Location = new System.Drawing.Point(12, 65);
            
            // MainForm
            this.ClientSize = new System.Drawing.Size(370, 120);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txtPassword);
            this.Controls.Add(this.btnGenerate);
            this.Controls.Add(this.txtComputerName);
            this.Text = "Local Admin Password Generator";
            this.ResumeLayout(false);
        }

        private System.Windows.Forms.TextBox txtComputerName;
        private System.Windows.Forms.Button btnGenerate;
        private System.Windows.Forms.TextBox txtPassword;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
    }
}
4. PowerShell Script to Set Local Admin Password

Use your DLL in PowerShell to generate and set the password on local or remote workstations:

Local Workstation Script

# Load the DLL
Add-Type -Path "C:\Path\To\OrgPasswordGenerator.dll"

# Get local computer name
$computerName = $env:COMPUTERNAME

# Generate password
$password = [PasswordGenerator]::GeneratePassword($computerName)

# Set local admin password (replace "Administrator" with your admin account name)
$adminUser = Get-LocalUser -Name "Administrator"
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
Set-LocalUser -InputObject $adminUser -Password $securePassword

Write-Host "Successfully set local admin password for $computerName" -ForegroundColor Green

Remote Workstations (PSRemoting Enabled)

$targetComputers = @("Workstation01", "Workstation02", "Workstation03")
$dllNetworkPath = "\\FileServer\Shared\OrgPasswordGenerator.dll"

Invoke-Command -ComputerName $targetComputers -ScriptBlock {
    param($dllPath)
    Add-Type -Path $dllPath
    $computerName = $env:COMPUTERNAME
    $password = [PasswordGenerator]::GeneratePassword($computerName)
    $adminUser = Get-LocalUser -Name "Administrator"
    $securePassword = ConvertTo-SecureString $password -AsPlainText -Force
    Set-LocalUser -InputObject $adminUser -Password $securePassword
} -ArgumentList $dllNetworkPath

Write-Host "Passwords updated for all target workstations" -ForegroundColor Green
Critical Security Notes
  • Protect the Secret Key: If an attacker gains access to _secretKey, they can generate passwords for any computer in your org. Store it in a secure vault or use DPAPI to encrypt it in your config.
  • Deterministic vs. Random: This logic is intentionaly deterministic (same computer name = same password) to avoid needing a central password store. If you ever need to rotate passwords, update the secret key.
  • Complexity Rules: Adjust the EnsureComplexity method to match your organization's password policy (e.g., add more special characters, enforce specific length ranges).

内容的提问来源于stack exchange,提问作者Appsum Solutions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:37:03