Давайте разберем этот интересный гибридный скрипт:
Первые строки скрипта представляют собой "полиглот" - код, который может быть интерпретирован несколькими языками программирования:
```
set @x=0; /*
@echo off
ver |>NUL find /v "5." && if "%~1"=="" cscript.exe //nologo //e:jscript "%~f0"& exit /b
```
Это хитрая конструкция, которая:
1. Начинается как cmd-скрипт (`@set @x=0;`)
2. Открывает многострочный комментарий в JavaScript (`/*`)
3. Выключает вывод команд в cmd (`@echo off`)
4. Проверяет версию Windows и если скрипт запущен без параметров, перезапускает сам себя через cscript.exe в режиме JavaScript
Последняя строка скрипта:
```javascript
*/new ActiveXObject('Shell.Application').ShellExecute (WScript.ScriptFullName,'Admin','','runas',1);
```
закрывает JavaScript-комментарий и содержит код для повышения привилегий - перезапуска скрипта с правами администратора.
Это техника самоповышения привилегий (UAC bypass), которая позволяет скрипту перезапустить себя с правами администратора, если он был запущен от обычного пользователя.
Основная часть скрипта написана на PowerShell и использует Windows Forms для создания графического интерфейса. Согласно документации [learn.microsoft.com](https://learn.microsoft.com/en-us/dotnet/api/syste...), скрипт создает форму для ввода даты, которая будет использоваться для настройки BIOS времени виртуальной машины VirtualBox.
Такая сложная структура используется для:
1. Обеспечения запуска с правами администратора
2. Совместимости с разными версиями Windows
3. Комбинирования возможностей разных языков скриптования Windows
PowerShell используется в этом скрипте для основной функциональности, и его часть начинается после строк:
```
;@echo off
;@Findstr -bv ;@ "%~f0" | powershell -noprofile -command - & goto:eof
```
Эта конструкция особенно интересна, потому что:
1. Использует Findstr для фильтрации содержимого файла, пропуская строки, начинающиеся с `;@`
2. Передает отфильтрованное содержимое в PowerShell через пайп (`|`)
3. Запускает PowerShell без профиля (`-noprofile`) для ускорения загрузки
PowerShell был выбран для основной части скрипта по нескольким причинам:
1. **Объектная модель**: Как отмечается в [thenewandshiny.com](https://thenewandshiny.com/powershell-everywhere/), PowerShell работает с объектами, а не с текстом, что делает его более надежным для работы с системными компонентами.
2. **Удобство работы с GUI**: PowerShell позволяет легко создавать Windows Forms для пользовательского интерфейса, что используется в функции `CustomInputBox`
3. **Управление VirtualBox**: PowerShell предоставляет удобные средства для запуска процессов и управления VirtualBox через `VBoxManage`
4. **Работа с датами**: PowerShell имеет мощные средства для работы с датами и временем, что критично для этого скрипта
Важно отметить, что в скрипте используется разделение на Windows PowerShell и PowerShell Core. Как упоминается в [get-powershellblog.blogspot.com](https://get-powershellblog.blogspot.com/2017/10/wh...), это важно учитывать при работе с разными версиями PowerShell.
Скрипт использует стандартный формат командлетов PowerShell `Verb-Noun`, хотя, как отмечается в [scoop-docs.vercel.app](https://scoop-docs.vercel.app/docs/misc/Why-PowerS...), такой формат может казаться излишне многословным, но он обеспечивает четкую структуру и понятность команд.
Основная функциональность скрипта:
1. Создает GUI для ввода даты
2. Проверяет корректность введенной даты
3. Настраивает время BIOS для виртуальной машины VirtualBox
4. Запускает виртуальную машину с модифицированными настройками времени
В скрипте время настраивается несколькими ключевыми командами:
1. Сначала отключается синхронизация времени с хостом:
```powershell
start-process $VB_MANAGE 'setextradata', $vmname, 'VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled 1' -NoNewWindow
```
2. Затем вычисляется смещение времени в миллисекундах:
```powershell
$timeoffset_milliseconds='{0:0}' -f ([datetime]$date - [datetime]::Now).TotalMilliseconds
```
3. И наконец, применяется смещение времени BIOS:
```powershell
start-process $VB_MANAGE 'modifyvm', $vmname, '--biossystemtimeoffset', $timeoffset_milliseconds -NoNewWindow
```
Здесь важно отметить несколько моментов:
- Используется VBoxManage - утилита командной строки VirtualBox (путь хранится в переменной `$VB_MANAGE`)
- Смещение вычисляется как разница между желаемым временем (`$date`) и текущим системным временем
- Параметр `--biossystemtimeoffset` устанавливает смещение времени BIOS в миллисекундах
После установки времени виртуальная машина запускается командой:
```powershell
start-process $VB_MANAGE startvm, $vmname
```
Похожий подход используется в проекте [github.com/bitbank2/rtc_setter](https://github.com..., где также реализована настройка времени, но для реального RTC (часов реального времени), а не виртуальной машины.
Важно понимать, что этот скрипт не просто устанавливает время, а именно смещение относительно системного времени хоста, что позволяет виртуальной машине работать с другой датой, но сохранять корректный ход времени.
deb http://deb.debian.org/debian bullseye main
deb-src http://deb.debian.org/debian bullseye main
deb http://deb.debian.org/debian-security/ bullseye-security main
deb-src http://deb.debian.org/debian-security/ bullseye-security main
deb http://deb.debian.org/debian bullseye-updates main
deb-src http://deb.debian.org/debian bullseye-updates main
[generic]
allowlist = true
[sda]
exportname = /dev/sda
[sdb]
exportname = /dev/sdb
# и так для каждого диска в машине
service nbd-server restart
sudo modprobe nbd
sudo nbd-client -name sda ip-адрес-мащины-nbd-server /dev/nbd0
# и так для каждого диска, поменяв например sdb и /dev/nbd1
dd if=/dev/nbd0 of=/dev/sda bs=1024k status=progress