update port remote change
This commit is contained in:
@@ -425,6 +425,76 @@ PS;
|
||||
return "Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
protected function CommandChangePort(string $cmd, bool $expectJson = false)
|
||||
{
|
||||
$auth = $this->LoginAuth();
|
||||
if (!$auth)
|
||||
return "Login_Fail";
|
||||
|
||||
$esc = fn(string $v) => str_replace("'", "''", $v);
|
||||
|
||||
$server = $esc($this->apiUri ?? '');
|
||||
$user = $esc($this->username ?? '');
|
||||
$pass = $esc($this->password ?? '');
|
||||
|
||||
// PowerShell script template
|
||||
$psTemplate = <<<'PS'
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
$InformationPreference = 'SilentlyContinue'
|
||||
$WarningPreference = 'SilentlyContinue'
|
||||
$ErrorActionPreference = 'Stop'
|
||||
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||
|
||||
Import-Module VMware.PowerCLI -ErrorAction Stop
|
||||
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope Session -Confirm:$false | Out-Null
|
||||
Connect-VIServer -Server '<SERVER>' -User '<USER>' -Password '<PASS>' | Out-Null
|
||||
|
||||
& {
|
||||
<CMD>
|
||||
}
|
||||
PS;
|
||||
|
||||
$psScript = strtr($psTemplate, [
|
||||
'<SERVER>' => $server,
|
||||
'<USER>' => $user,
|
||||
'<PASS>' => $pass,
|
||||
'<CMD>' => $cmd,
|
||||
]);
|
||||
|
||||
// Encode UTF-16LE cho -EncodedCommand
|
||||
$encoded = base64_encode(mb_convert_encoding($psScript, 'UTF-16LE', 'UTF-8'));
|
||||
$action = "powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -EncodedCommand $encoded";
|
||||
|
||||
try {
|
||||
$stream = ssh2_exec($auth, $action);
|
||||
if (!$stream)
|
||||
return "ssh2_exec failed";
|
||||
$err = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR);
|
||||
stream_set_blocking($stream, true);
|
||||
stream_set_blocking($err, true);
|
||||
|
||||
$out = stream_get_contents($stream) ?: '';
|
||||
$errOut = stream_get_contents($err) ?: '';
|
||||
|
||||
if ($expectJson) {
|
||||
// CẮT JSON cuối: {...} hoặc [...]
|
||||
$trimmed = trim($out);
|
||||
// đơn giản: bắt khối { ... } hoặc [ ... ] ở cuối chuỗi
|
||||
if (preg_match('~(\{.*\}|\[.*\])\s*$~s', $trimmed, $m)) {
|
||||
return $m[1];
|
||||
}
|
||||
// không tìm thấy → trả nguyên STDOUT (để caller log raw)
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
// Trường hợp không kỳ vọng JSON: giữ nguyên hành vi cũ (append STDERR)
|
||||
return $out . ($errOut ? "\n[STDERR]\n" . $errOut : '');
|
||||
} catch (\Throwable $e) {
|
||||
return "Error: " . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function resetGuestPasswordViaPs1(string $vmName, string $guestUser, string $guestPassword, string $newPassword, string $targetUser = 'Administrator'): array|string
|
||||
{
|
||||
// File ps1 chạy được ngoài PowerShell: bạn đã test ok
|
||||
@@ -461,6 +531,60 @@ PS;
|
||||
return $data ?: $raw; // nếu chưa parse được, trả raw để debug
|
||||
}
|
||||
|
||||
|
||||
public function changeRDPPortWindows(string $vmName, string $guestUser, string $guestPassword, string $newPort): array|string
|
||||
{
|
||||
$psFile = "C:\\CLISave\\AssignIP\\change-rdp-port.ps1";
|
||||
$q = fn(string $v) => str_replace("'", "''", $v);
|
||||
|
||||
// Dùng -VMName (string). Alias -VMNames cũng ok, nhưng mình set đúng tên tham số.
|
||||
$args = " -VMName '" . $q($vmName) . "'";
|
||||
$args .= " -GuestUser '" . $q($guestUser) . "'";
|
||||
$args .= " -GuestPassword '" . $q($guestPassword) . "'"; // khớp tên tham số trong script 1-VM
|
||||
$args .= " -NewPort " . (int) $newPort;
|
||||
|
||||
$cmd = "& '$psFile'$args";
|
||||
|
||||
// Nếu đã có phiên bản CommandRSP($cmd, bool $expectJson) → bật expectJson để không trộn STDERR
|
||||
$raw = method_exists($this, 'CommandRSP')
|
||||
? ($this->CommandChangePort($cmd, true) ?? '')
|
||||
: '';
|
||||
|
||||
if ($raw === 'Login_Fail' || $raw === false || $raw === null) {
|
||||
return "Login_Fail";
|
||||
}
|
||||
$raw = trim($raw);
|
||||
|
||||
// CẮT LẤY KHỐI JSON CUỐI (object hoặc array) nếu có noise
|
||||
if (!preg_match('~(\{(?:[^{}]|(?1))*\}|\[(?:[^\[\]]|(?0))*\])\s*$~s', $raw, $m)) {
|
||||
// fallback đơn giản hơn
|
||||
if (preg_match('~(\{.*\}|\[.*\])\s*$~s', $raw, $m)) {
|
||||
$raw = $m[1];
|
||||
}
|
||||
} else {
|
||||
$raw = $m[1];
|
||||
}
|
||||
|
||||
$data = json_decode($raw, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'JSON parsing failed',
|
||||
'raw_output' => $raw,
|
||||
'json_error' => json_last_error_msg()
|
||||
];
|
||||
}
|
||||
|
||||
// Script 1-VM trả về 1 object, nhưng nếu lỡ trả mảng thì lấy phần tử đầu
|
||||
if (isset($data[0])) {
|
||||
$data = $data[0];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function getAllNetwork()
|
||||
{
|
||||
$check = $this->checkApiExits();
|
||||
|
||||
Reference in New Issue
Block a user