Итак,
если вы просрали пароль на KES10 и имеете только удалённый доступ к хосту.
или же, если вам надо запустить какую-то команду в безопасном режиме
Потребуется некоторая предварительная подготовка
1. Создать на хосте пользователя с правами локального администратора
2. Создать на хосте папку (например, c:\Scripts) и скопировать в неё (только!) необходимые скрипты.
Ваши скрипты безопасного режима должны соответствовать маске SafeMode-*.ps1. Скрипт ищет их в той же папке, где находится сам.
Если же вам надо запустить что-то другое, это что-то другое можно указать в параметре -SafeCommand скрипта. Например, вы можете указать свой CMD файл и вписать в него всё,
что хотели.
Использование
Execute-SafeMode.ps1 -UserName Admin -DomainName MyDomain -Password AdminPassword -RebootImmediately -SafeCommand "cmd.exe /c c:\windows\temp\1.tmp"Execute-SafeMode.ps1 -UserName Admin -Password AdminPassword
Параметры
UserName - обязательный, имя пользователя с правами администратора. пользователь должен иметь возможность входа в безопасном режиме, иначе хост так и останется в безопасном режиме.DomainName - необязательный. Если не указан, то принимается название хоста.
Password - обязательный. пароль пользователя с административными правами
RebootImmediately - необязательный. флажок немедленной перезагрузки. Если указать, скрипт немедленно перезагрузит хост в безопасный режим
SafeCommand - необязательный. команда для безопасного режима
Порядок работы скрипта
При запуске в нормальном режиме
- скрипт устанавливает себя в ключ RunOnce для запуска в безопасном режиме
- скрипт устанавливает указанные логин и пароль для автоматического входа (AutoAdminLogon)
- скрипт устанавливает флаг загрузки в безопасном режиме (с помощью bcdedit)
- скрипт выполняет перезагрузку, если указан флаг немедленного исполнения
- происходит автоматический вход в систему под указанной учётной записью
- происходит автоматический запуск скрипта
- скрипт выполняет команду, переданную в параметре SafeCommand
- скрипт ищет рядом с собой файлы по маске SafeBoot-*.ps1 и последовательно выполняет их. Порядок выполнения не определён
- скрипт удаляет параметры автоматического входа в систему (AutoAdminLogon)
- скрипт устанавливает флаг загрузки в нормальном режиме
- скрипт выполняет перезагрузку
# Execute-SafeMode.ps1
# LastUpdate: 21.08.2017 17:30:04
#
[CmdletBinding()]
Param(
[string]$UserName = "",
[string]$Domain = "",
[string]$Password = "",
[switch]$RebootImmediately = $false,
[string]$SafeCommand = ""
)
$SaveVerbosePreference = $VerbosePreference
$VerbosePreference = 'Continue'
$SaveCurrentDir = Get-Location
$keyRunOnce = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce"
$keyWinlogon = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
$runEntry = "*ExecuteSafeMode"
$SaveVerbosePreference = $VerbosePreference
$VerbosePreference = 'Continue'
$PluginScriptMask = "SafeMode-*.ps1"
$MyScript = $MyInvocation.MyCommand.Path
$WorkDir = Split-Path ($MyInvocation.MyCommand.Path) -Parent
$SafeBootScript = "$WorkDir\safeboot.cmd"
$LogFile = [IO.Path]::ChangeExtension($MyInvocation.MyCommand.Path, "log")
Set-Location $WorkDir
$IsNormalBoot = (Get-WmiObject -Class Win32_ComputerSystem |
Select-Object -ExpandProperty BootupState) -like '*Normal*'
function myeval($cmd)
{
if ($cmd[0] -eq '"')
{
Invoke-Expression "& $cmd"
}
else
{
Invoke-Expression $cmd
}
}
function Write-RegistryString($Path, $Name, $Value)
{
Remove-ItemProperty -Path $Path -Name $Name | Out-Null
New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType String
}
Write-Verbose "Arguments is"
Write-Verbose "`tUserName : $UserName"
Write-Verbose "`tDomain : $Domain"
Write-Verbose "`tPassword : $Password"
Write-Verbose "`tRebootImmediately : $RebootImmediately"
Write-Verbose "`tSafeCommand : $SafeCommand"
Write-Verbose ""
Write-Verbose "`tIsNormalBoot : $IsNormalBoot"
# проверка аргументов
if ($IsNormalBoot)
{
if ( [string]::IsNullOrEmpty($UserName) )
{
throw New-Object System.ArgumentException("Parameter -UserName must not be NULL")
}
if ( [string]::IsNullOrEmpty($Password) )
{
throw New-Object System.ArgumentException("Parameter -Password must not be NULL")
}
}
if ($IsNormalBoot)
{
# создаём файл safeboot.cmd с указанной командой
$CommandLine = "PowerShell.exe -NoProfile -ExecutionPolicy Bypass -File {0} -SafeCommand `"{1}`"" -f $MyScript, $SafeCommand
$CommandLine | Set-Content -Path $SafeBootScript -Force
# устанавливаем в HKLM\\RunOnce наш скрипт safeboot.cmd
if ( !(Test-Path -Path $keyRunOnce) )
{
New-Item -Path $keyRunOnce -Force
}
Remove-ItemProperty -Path $keyRunOnce -Name $runEntry -Force | Out-Null
New-ItemProperty -Path $keyRunOnce -Name $runEntry -Value $SafeBootScript -PropertyType String -Force | Out-Null
# назначаем AutoAdminLogon пользователя
if ( !(Test-Path -Path $keyWinlogon) )
{
New-Item -Path $keyWinlogon -Force | Out-Null
}
Remove-ItemProperty -Path $keyWinlogon -Name "AutoAdminLogon" | Out-Null
New-ItemProperty -Path $keyWinlogon -Name "AutoAdminLogon" -Value "1" -PropertyType String -Force
if ( [string]::IsNullOrEmpty($Domain) )
{
$Domain = $env:COMPUTERNAME
}
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultDomainName" -Force | Out-Null
New-ItemProperty -Path $keyWinlogon -Name "DefaultDomainName" -Value $Domain
-PropertyType String -Force | Out-Null
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultUserName" -Force | Out-Null
New-ItemProperty -Path $keyWinlogon -Name "DefaultUserName" -Value $UserName
-PropertyType String -Force | Out-Null
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultPassword" -Force | Out-Null
New-ItemProperty -Path $keyWinlogon -Name "DefaultPassword" -Value $Password
-PropertyType String -Force | Out-Null
# устанавливаем следующую перезагрузку в безопасном режиме
& bcdedit /set `{current`} safeboot minimal
# перегружаемся
if ($RebootImmediately)
{
Restart-Computer -Force
}
}
else # Safe Mode
{
# удаляем Auto Logon пользователя
if ( !(Test-Path -Path $keyWinlogon) )
{
New-Item -Path $keyWinlogon -Force
}
Remove-ItemProperty -Path $keyWinlogon -Name "AutoAdminLogon" | Out-Null
New-ItemProperty -Path $keyWinlogon -Name "AutoAdminLogon" -Value "0" -PropertyType String | Out-Null
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultPassword" -Force | Out-Null
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultDomainName" -Force | Out-Null
Remove-ItemProperty -Path $keyWinlogon -Name "DefaultUserName" -Force | Out-Null
# устанавливаем следующую перезагрузку в нормальный режим
& bcdedit /deletevalue `{current`} safeboot
# удаляем SafeBoot.cmd
Remove-Item -Path $SafeBootScript -Force | Out-Null
# выполняем команду пользователя
if ( ![string]::IsNullOrEmpty($SafeCommand) )
{
try
{
"Invoke $SafeCommand :" | Out-File -FilePath $LogFile -Append -Encoding unicode
myeval $SafeCommand | Out-File -FilePath $LogFile -Append -Encoding unicode
}
catch
{
"ERROR: $($_.Exception.Message)" | Out-File $LogFile -Append -Encoding unicode
}
}
Get-ChildItem -Path $WorkDir -Filter "SafeMode-*.ps1" |
Select-Object -ExpandProperty FullName |
ForEach-Object {
$SafeModePlugin = $_
try
{
"Invoke $SafeModePlugin :" | Out-File -FilePath $LogFile -Append -Encoding unicode
Invoke-Expression -Command $SafeModePlugin | Out-File -FilePath $LogFile -Append -Encoding unicode
"Invoke $SafeModePlugin : OK" | Out-File -FilePath $LogFile -Append -Encoding unicode
}
catch
{
"ERROR: $($_.Exception.Message)" | Out-File -FilePath $LogFile -Append -Encoding unicode
}
}
# перегружаемся
& shutdown.exe -r -f -t 3
}
$VerbosePreference = $SaveVerbosePreference
Set-Location $SaveCurrentDir