Code= Windows Service(background) служба, написанная в .Net 8) запуск от имени администратора
получение учетных данных:
- Способ 1: возврат CredMan.ps1 код 0, но ошибка сценария credman
- способ 2: Advapi32.dll возвращает ошибку 1168 «ERROR_NOT_FOUND»
вызов CredRead:
Код: Выделить всё
private static string? ReadCredential(string target, Func readFunc)
{
if (string.IsNullOrWhiteSpace(target))
{
throw new ArgumentException($"{nameof(target)} cannot be null or empty.", nameof(target));
}
nint credPtr = nint.Zero;
try
{
target = target.Trim();
bool success = CredRead(target, CredentialTypeEnum.CRED_TYPE.GENERIC, 0, out credPtr);
if (success)
{
CredentialEnum.CREDENTIAL credential = Marshal.PtrToStructure(credPtr);
return readFunc(credential);
}
}
catch (Exception ex)
{
Log.Error(ex, "Error reading credential");
}
finally
{
if (credPtr != nint.Zero)
{
CredFree(credPtr);
credPtr = nint.Zero;
}
}
return null;
}
CredRead:
Код: Выделить всё
//https://learn.microsoft.com/en-us/windows/win32/api/wincred/nf-wincred-credreada
[DllImport("Advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CredRead(string target, CredentialTypeEnum.CRED_TYPE type, int reservedFlag, out nint credentialPtr);
вызов сценария CreadMan.ps1:
Код: Выделить всё
private async Task ExecuteCredManCommand(string psCommand, CustomerHost host)
{
string scriptPath = GetScriptFullPath("CredMan.ps1");
psCommand = $"&{scriptPath + " " + $"-GetCred -Target '{host.CredentialName.Trim()}' -CredType Generic"}";
StringBuilder stdOutBuffer = new StringBuilder();
StringBuilder stdErrBuffer = new StringBuilder();
var result = Cli.Wrap("powershell")
.WithArguments($"-Command \"{psCommand}\"")
.WithValidation(CommandResultValidation.None)
.WithStandardOutputPipe(PipeTarget.ToStringBuilder(stdOutBuffer))
.WithStandardErrorPipe(PipeTarget.ToStringBuilder(stdErrBuffer))
.ListenAsync();
int exitCode = 0;
await foreach (var cmdEvent in result)
{
if (cmdEvent is ExitedCommandEvent exited)
{
exitCode = exited.ExitCode;
_logger.LogInformation($"Process exited; Code: {exited.ExitCode}");
}
}
// Parse the output to retrieve UserName and Password
string output = stdOutBuffer.ToString();
string[] lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
_logger.LogInformation($"CredMan Output: {lines}");
foreach (var line in lines)
{
//" UserName : k-is\\administrator"
if (line.Trim().StartsWith("UserName"))
{
host.UserName = line.Split(':')[1].Trim();
}
else if (line.Trim().StartsWith("Password"))
{
host.Password = line.Split(':')[1].Trim();
}
}
}
Функция CredMan, возвращающая ошибку на сервере:
ошибка " Write-Host «Учетные данные для типа $Target как $CredType не найдены».
Код: Выделить всё
#region Reading selected credential
if($GetCred)
{
if(-not $Target)
{
Write-Host "You must supply a target URI."
return
}
# may be [PsUtils.CredMan+Credential] or [Management.Automation.ErrorRecord]
[Object] $Cred = Read-Creds $Target $CredType
if($null -eq $Cred)
{
Write-Host "Credential for '$Target' as '$CredType' type was not found."
return
}
if($Cred -is [Management.Automation.ErrorRecord])
{
return $Cred
}
[String] $CredStr = @"
Found credentials as:
UserName : $($Cred.UserName)
Password : $($Cred.CredentialBlob)
Target : $($Cred.TargetName.Substring($Cred.TargetName.IndexOf("=")+1))
Updated : $([String]::Format("{0:yyyy-MM-dd HH:mm:ss}", $Cred.LastWritten.ToUniversalTime())) UTC
Comment : $($Cred.Comment)
"@
Write-Host $CredStr
}
#endregion
Когда я запускаю CredMan.ps1 в PowerShell ISE, он возвращает данные учетные данные успешно. код powershell:
Код: Выделить всё
cd pathofcredman
.\CredMan.ps1 -GetCred -Target NameOfTarget -CredType Generic
Я буду признателен, если кто-нибудь поможет мне, как двигаться дальше
Подробнее здесь: https://stackoverflow.com/questions/790 ... indows-ser