forked from extern/BloatyNosy
311 lines
16 KiB
PowerShell
311 lines
16 KiB
PowerShell
|
[cmdletbinding()]
|
|||
|
param (
|
|||
|
[Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string]
|
|||
|
$Username,
|
|||
|
|
|||
|
[Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [System.Security.SecureString]
|
|||
|
$Password,
|
|||
|
|
|||
|
[string]
|
|||
|
$Domain,
|
|||
|
|
|||
|
[Int]
|
|||
|
$AutoLogonCount,
|
|||
|
|
|||
|
[switch]
|
|||
|
$RemoveLegalPrompt,
|
|||
|
|
|||
|
[System.IO.FileInfo]
|
|||
|
$BackupFile
|
|||
|
)
|
|||
|
|
|||
|
begin {
|
|||
|
|
|||
|
[string] $WinlogonPath = "HKLM:\Software\Microsoft\Windows NT\CurrentVersion\Winlogon"
|
|||
|
[string] $WinlogonBannerPolicyPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System"
|
|||
|
|
|||
|
[string] $Enable = 1
|
|||
|
[string] $Disable = 0
|
|||
|
|
|||
|
#region C# Code to P-invoke LSA LsaStorePrivateData function.
|
|||
|
Add-Type @"
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Text;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace ComputerSystem
|
|||
|
{
|
|||
|
public class LSAutil
|
|||
|
{
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
private struct LSA_UNICODE_STRING
|
|||
|
{
|
|||
|
public UInt16 Length;
|
|||
|
public UInt16 MaximumLength;
|
|||
|
public IntPtr Buffer;
|
|||
|
}
|
|||
|
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
private struct LSA_OBJECT_ATTRIBUTES
|
|||
|
{
|
|||
|
public int Length;
|
|||
|
public IntPtr RootDirectory;
|
|||
|
public LSA_UNICODE_STRING ObjectName;
|
|||
|
public uint Attributes;
|
|||
|
public IntPtr SecurityDescriptor;
|
|||
|
public IntPtr SecurityQualityOfService;
|
|||
|
}
|
|||
|
|
|||
|
private enum LSA_AccessPolicy : long
|
|||
|
{
|
|||
|
POLICY_VIEW_LOCAL_INFORMATION = 0x00000001L,
|
|||
|
POLICY_VIEW_AUDIT_INFORMATION = 0x00000002L,
|
|||
|
POLICY_GET_PRIVATE_INFORMATION = 0x00000004L,
|
|||
|
POLICY_TRUST_ADMIN = 0x00000008L,
|
|||
|
POLICY_CREATE_ACCOUNT = 0x00000010L,
|
|||
|
POLICY_CREATE_SECRET = 0x00000020L,
|
|||
|
POLICY_CREATE_PRIVILEGE = 0x00000040L,
|
|||
|
POLICY_SET_DEFAULT_QUOTA_LIMITS = 0x00000080L,
|
|||
|
POLICY_SET_AUDIT_REQUIREMENTS = 0x00000100L,
|
|||
|
POLICY_AUDIT_LOG_ADMIN = 0x00000200L,
|
|||
|
POLICY_SERVER_ADMIN = 0x00000400L,
|
|||
|
POLICY_LOOKUP_NAMES = 0x00000800L,
|
|||
|
POLICY_NOTIFICATION = 0x00001000L
|
|||
|
}
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaRetrievePrivateData(
|
|||
|
IntPtr PolicyHandle,
|
|||
|
ref LSA_UNICODE_STRING KeyName,
|
|||
|
out IntPtr PrivateData
|
|||
|
);
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaStorePrivateData(
|
|||
|
IntPtr policyHandle,
|
|||
|
ref LSA_UNICODE_STRING KeyName,
|
|||
|
ref LSA_UNICODE_STRING PrivateData
|
|||
|
);
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaOpenPolicy(
|
|||
|
ref LSA_UNICODE_STRING SystemName,
|
|||
|
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
|
|||
|
uint DesiredAccess,
|
|||
|
out IntPtr PolicyHandle
|
|||
|
);
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaNtStatusToWinError(
|
|||
|
uint status
|
|||
|
);
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaClose(
|
|||
|
IntPtr policyHandle
|
|||
|
);
|
|||
|
|
|||
|
[DllImport("advapi32.dll", SetLastError = true, PreserveSig = true)]
|
|||
|
private static extern uint LsaFreeMemory(
|
|||
|
IntPtr buffer
|
|||
|
);
|
|||
|
|
|||
|
private LSA_OBJECT_ATTRIBUTES objectAttributes;
|
|||
|
private LSA_UNICODE_STRING localsystem;
|
|||
|
private LSA_UNICODE_STRING secretName;
|
|||
|
|
|||
|
public LSAutil(string key)
|
|||
|
{
|
|||
|
if (key.Length == 0)
|
|||
|
{
|
|||
|
throw new Exception("Key lenght zero");
|
|||
|
}
|
|||
|
|
|||
|
objectAttributes = new LSA_OBJECT_ATTRIBUTES();
|
|||
|
objectAttributes.Length = 0;
|
|||
|
objectAttributes.RootDirectory = IntPtr.Zero;
|
|||
|
objectAttributes.Attributes = 0;
|
|||
|
objectAttributes.SecurityDescriptor = IntPtr.Zero;
|
|||
|
objectAttributes.SecurityQualityOfService = IntPtr.Zero;
|
|||
|
|
|||
|
localsystem = new LSA_UNICODE_STRING();
|
|||
|
localsystem.Buffer = IntPtr.Zero;
|
|||
|
localsystem.Length = 0;
|
|||
|
localsystem.MaximumLength = 0;
|
|||
|
|
|||
|
secretName = new LSA_UNICODE_STRING();
|
|||
|
secretName.Buffer = Marshal.StringToHGlobalUni(key);
|
|||
|
secretName.Length = (UInt16)(key.Length * UnicodeEncoding.CharSize);
|
|||
|
secretName.MaximumLength = (UInt16)((key.Length + 1) * UnicodeEncoding.CharSize);
|
|||
|
}
|
|||
|
|
|||
|
private IntPtr GetLsaPolicy(LSA_AccessPolicy access)
|
|||
|
{
|
|||
|
IntPtr LsaPolicyHandle;
|
|||
|
|
|||
|
uint ntsResult = LsaOpenPolicy(ref this.localsystem, ref this.objectAttributes, (uint)access, out LsaPolicyHandle);
|
|||
|
|
|||
|
uint winErrorCode = LsaNtStatusToWinError(ntsResult);
|
|||
|
if (winErrorCode != 0)
|
|||
|
{
|
|||
|
throw new Exception("LsaOpenPolicy failed: " + winErrorCode);
|
|||
|
}
|
|||
|
|
|||
|
return LsaPolicyHandle;
|
|||
|
}
|
|||
|
|
|||
|
private static void ReleaseLsaPolicy(IntPtr LsaPolicyHandle)
|
|||
|
{
|
|||
|
uint ntsResult = LsaClose(LsaPolicyHandle);
|
|||
|
uint winErrorCode = LsaNtStatusToWinError(ntsResult);
|
|||
|
if (winErrorCode != 0)
|
|||
|
{
|
|||
|
throw new Exception("LsaClose failed: " + winErrorCode);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void SetSecret(string value)
|
|||
|
{
|
|||
|
LSA_UNICODE_STRING lusSecretData = new LSA_UNICODE_STRING();
|
|||
|
|
|||
|
if (value.Length > 0)
|
|||
|
{
|
|||
|
//Create data and key
|
|||
|
lusSecretData.Buffer = Marshal.StringToHGlobalUni(value);
|
|||
|
lusSecretData.Length = (UInt16)(value.Length * UnicodeEncoding.CharSize);
|
|||
|
lusSecretData.MaximumLength = (UInt16)((value.Length + 1) * UnicodeEncoding.CharSize);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//Delete data and key
|
|||
|
lusSecretData.Buffer = IntPtr.Zero;
|
|||
|
lusSecretData.Length = 0;
|
|||
|
lusSecretData.MaximumLength = 0;
|
|||
|
}
|
|||
|
|
|||
|
IntPtr LsaPolicyHandle = GetLsaPolicy(LSA_AccessPolicy.POLICY_CREATE_SECRET);
|
|||
|
uint result = LsaStorePrivateData(LsaPolicyHandle, ref secretName, ref lusSecretData);
|
|||
|
ReleaseLsaPolicy(LsaPolicyHandle);
|
|||
|
|
|||
|
uint winErrorCode = LsaNtStatusToWinError(result);
|
|||
|
if (winErrorCode != 0)
|
|||
|
{
|
|||
|
throw new Exception("StorePrivateData failed: " + winErrorCode);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
"@
|
|||
|
#endregion
|
|||
|
}
|
|||
|
|
|||
|
process {
|
|||
|
|
|||
|
try {
|
|||
|
$ErrorActionPreference = "Stop"
|
|||
|
|
|||
|
$decryptedPass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
|
|||
|
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
|
|||
|
)
|
|||
|
|
|||
|
if ($BackupFile) {
|
|||
|
# Initialize the hash table with a string comparer to allow case sensitive keys.
|
|||
|
# This allows differentiation between the winlogon and system policy logon banner strings.
|
|||
|
$OrigionalSettings = New-Object System.Collections.Hashtable ([system.stringcomparer]::CurrentCulture)
|
|||
|
|
|||
|
$OrigionalSettings.AutoAdminLogon = (Get-ItemProperty $WinlogonPath ).AutoAdminLogon
|
|||
|
$OrigionalSettings.ForceAutoLogon = (Get-ItemProperty $WinlogonPath).ForceAutoLogon
|
|||
|
$OrigionalSettings.DefaultUserName = (Get-ItemProperty $WinlogonPath).DefaultUserName
|
|||
|
$OrigionalSettings.DefaultDomainName = (Get-ItemProperty $WinlogonPath).DefaultDomainName
|
|||
|
$OrigionalSettings.DefaultPassword = (Get-ItemProperty $WinlogonPath).DefaultPassword
|
|||
|
$OrigionalSettings.AutoLogonCount = (Get-ItemProperty $WinlogonPath).AutoLogonCount
|
|||
|
|
|||
|
# The winlogon logon banner settings.
|
|||
|
$OrigionalSettings.LegalNoticeCaption = (Get-ItemProperty $WinlogonPath).LegalNoticeCaption
|
|||
|
$OrigionalSettings.LegalNoticeText = (Get-ItemProperty $WinlogonPath).LegalNoticeText
|
|||
|
|
|||
|
# The system policy logon banner settings.
|
|||
|
$OrigionalSettings.legalnoticecaption = (Get-ItemProperty $WinlogonBannerPolicyPath).legalnoticecaption
|
|||
|
$OrigionalSettings.legalnoticetext = (Get-ItemProperty $WinlogonBannerPolicyPath).legalnoticetext
|
|||
|
|
|||
|
$OrigionalSettings | Export-Clixml -Depth 10 -Path $BackupFile
|
|||
|
}
|
|||
|
|
|||
|
# Store the password securely.
|
|||
|
$lsaUtil = New-Object ComputerSystem.LSAutil -ArgumentList "DefaultPassword"
|
|||
|
$lsaUtil.SetSecret($decryptedPass)
|
|||
|
|
|||
|
# Store the autologon registry settings.
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name AutoAdminLogon -Value $Enable -Force
|
|||
|
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name DefaultUserName -Value $Username -Force
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name DefaultDomainName -Value $Domain -Force
|
|||
|
|
|||
|
if ($AutoLogonCount) {
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name AutoLogonCount -Value $AutoLogonCount -Force
|
|||
|
} else {
|
|||
|
Remove-ItemProperty -Path $WinlogonPath -Name AutoLogonCount -ErrorAction SilentlyContinue
|
|||
|
}
|
|||
|
|
|||
|
if ($RemoveLegalPrompt) {
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name LegalNoticeCaption -Value $null -Force
|
|||
|
Set-ItemProperty -Path $WinlogonPath -Name LegalNoticeText -Value $null -Force
|
|||
|
|
|||
|
Set-ItemProperty -Path $WinlogonBannerPolicyPath -Name legalnoticecaption -Value $null -Force
|
|||
|
Set-ItemProperty -Path $WinlogonBannerPolicyPath -Name legalnoticetext -Value $null -Force
|
|||
|
}
|
|||
|
} catch {
|
|||
|
throw 'Failed to set auto logon. The error was: "{0}".' -f $_
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
<#
|
|||
|
.SYNOPSIS
|
|||
|
Enables auto logon using the specified username and password.
|
|||
|
|
|||
|
.PARAMETER Username
|
|||
|
The username of the user to automatically logon as.
|
|||
|
|
|||
|
.PARAMETER Password
|
|||
|
The password for the user to automatically logon as.
|
|||
|
|
|||
|
.PARAMETER Domain
|
|||
|
The domain of the user to automatically logon as.
|
|||
|
|
|||
|
.PARAMETER AutoLogonCount
|
|||
|
The number of logons that auto logon will be enabled.
|
|||
|
|
|||
|
.PARAMETER RemoveLegalPrompt
|
|||
|
Removes the system banner to ensure interventionless logon.
|
|||
|
|
|||
|
.PARAMETER BackupFile
|
|||
|
If specified the existing settings such as the system banner text will be backed up to the specified file.
|
|||
|
|
|||
|
.EXAMPLE
|
|||
|
PS C:\> Set-SecureAutoLogon `
|
|||
|
-Username $env:USERNAME `
|
|||
|
-Password (Read-Host -AsSecureString) `
|
|||
|
-AutoLogonCount 2 `
|
|||
|
-RemoveLegalPrompt `
|
|||
|
-BackupFile "C:\WinlogonBackup.xml"
|
|||
|
|
|||
|
.INPUTS
|
|||
|
None.
|
|||
|
|
|||
|
.OUTPUTS
|
|||
|
None.
|
|||
|
|
|||
|
.NOTES
|
|||
|
Revision History:
|
|||
|
2011-04-19 : Andy Arismendi - Created.
|
|||
|
2011-09-29 : Andy Arismendi - Changed to use LSA secrets to store password securely.
|
|||
|
|
|||
|
.LINK
|
|||
|
http://support.microsoft.com/kb/324737
|
|||
|
|
|||
|
.LINK
|
|||
|
http://msdn.microsoft.com/en-us/library/aa378750
|
|||
|
|
|||
|
#>
|