使用 WinAPI,我们可以这样做:
Param(
[string] $Password ,
[string] $CertFilePath
)
function ExecuteCommand([string]$message)
{
try{
foreach ($char in [char[]]$message) {
[void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, [int]$char, 0)
}
[void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, 13, 0)
Sleep 3
}catch{
}
}
Add-Type -Name ConsoleUtils -Namespace WPIA -MemberDefinition @'
[DllImport("user32.dll")]
public static extern int PostMessage(int hWnd, uint Msg, int wParam, int lParam);
public const int WM_CHAR = 0x0102;
'@
$Win32API = Add-Type -Name Funcs -Namespace Win32 -PassThru -MemberDefinition @'
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
[DllImport("kernel32.dll")]
public static extern uint GetLastError();
'@
[System.Reflection.Assembly]::Load("Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
[System.Reflection.Assembly]::Load("Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object Microsoft.Build.Tasks.ResolveKeySource
$publish.KeyFile=$CertFilePath
try
{
$publish.Execute()
}
catch{
$VsKey= [regex]::match($error[0].Exception,'VS_KEY_[A-F0-9]+').Value
$VsKey =$VsKey -replace "`n|`r"
}
$quotedCertPath='"'+$CertFilePath+'"'
Write-Host 'VsKey='$VsKey
start cmd
$proc=Get-Process | Where-Object {$_.Name -like "*cmd*"}
$proc.MainWindowTitle
$handle = $proc.MainWindowHandle
'1:'+$handle
if($handle -eq 0){
$handle=$Win32API::FindWindow([IntPtr]::Zero, 'C:\WINDOWS\system32\cmd.exe')
'2:'+$handle
}
if($handle -eq 0){
$handle=$Win32API::FindWindow('C:\WINDOWS\system32\cmd.exe', [IntPtr]::Zero)
'3:'+$handle
}
if($handle -eq 0){
$proc2 = Start-Process cmd.exe -PassThru
$proc2
Get-Process -id $proc2.Id
Sleep 3;
$handle = (Get-Process -id $proc2.Id).MainWindowHandle
$handle
$proc.MainWindowHandle
$proc.Refresh()
Sleep 3;
$proc.MainWindowHandle
}
Write-Host 'Handle='$handle
ExecuteCommand 'echo Starting > d:\a\1\s\Authenticode\log.txt'
$SnCommand=[string]::Format(".\sn.exe -i {0} {1}",$quotedCertPath,$VsKey)
ExecuteCommand $SnCommand
ExecuteCommand $Password