$computer_sys.Put() | Out-Null
...
$page_file.Put() | Out-Null
Set-WmiInstance -Class Win32_PageFileSetting -Arguments @{name="C:\pagefile.sys"; InitialSize = 4096; MaximumSize = 8192} -EnableAllPrivileges | Out-Null
Давайте разберем этот интересный гибридный скрипт:
Первые строки скрипта представляют собой "полиглот" - код, который может быть интерпретирован несколькими языками программирования:
```
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 (часов реального времени), а не виртуальной машины.
Важно понимать, что этот скрипт не просто устанавливает время, а именно смещение относительно системного времени хоста, что позволяет виртуальной машине работать с другой датой, но сохранять корректный ход времени.
Add-Type -AssemblyName System.Windows.Forms
# Создание диалогового окна сохранения файла
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveFileDialog.InitialDirectory = [System.Environment]::GetFolderPath('Desktop') # Стартовый каталог
$saveFileDialog.Filter = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*" # Фильтр типов файлов
$saveFileDialog.Title = "Выберите место для сохранения файла"
$saveFileDialog.DefaultExt = "txt" # Расширение по умолчанию
# Отображение диалога и обработка результата
if ($saveFileDialog.ShowDialog() -eq "OK") {
$savePath = $saveFileDialog.FileName
Write-Host "Файл будет сохранен по пути: $savePath"
} else {
Write-Host "Сохранение отменено пользователем."
}
for i in */; do zip -r "${i%/}.zip" "$i"; done
find . -type f -name '*.db' -exec zip -m {}.zip {} \;
for %%F in ("%source_folder%\*") do (
call rling "%%~fF" "%compare_folder%"
type result.txt >> %output_file%
del /q result.txt
if (!(Test-Path $outputFile)) {
New-Item -Path $outputFile -Force | Out-Null
}
Get-ChildItem -Path $sourceFolder -File | ForEach-Object {
& rling $_.FullName $compareFolder
Get-Content -Path '.\result.txt' | Add-Content -Path $outputFile
Remove-Item -Path '.\result.txt' -ErrorAction SilentlyContinue
}
-Credential
Specifies the account used by the service as the Service Logon Account.
где каждому сотруднику присвоен ПК
$threadslimit = 8
$collection = @{}
$synccollection = [System.Collections.Hashtable]::Synchronized($collection)
1..1000 | ForEach-Object {
$data = @('some', 'valuable', 'text', 'data')
$synccollection.Add($_, $data)
}
#выводим созданную коллекцию до изменений, просто чтобы можно было сравнить
$synccollection
$keys = @($synccollection.Keys)
$keys | ForEach-Object -Parallel {
$synccollectionscope = $using:synccollection
# Здесь на самом деле какая-то функция, которая возвращает строку
$format = 'Changed data'
# Изменяем одно из полей, напоминаю, по ключам лежат массивы
$synccollectionscope[$_][3] = $format
# Тут вывод чтобы просто отслеживать выполнение скрипта
Write-Output "Data was changed"
} -ThrottleLimit $threadslimit
# Вывод самой коллекции в консоль, чтобы убедиться, что значения поменялись
$synccollection
Under Exchange 2013 Architecture:
“Second, Outlook clients no longer connect to a server FQDN as they have done in all previous versions of Exchange. Outlook uses Autodiscover to create a new connection point comprised of mailbox GUID, @ symbol, and the domain portion of the user’s primary SMTP address. This simple change results in a near elimination of the unwelcome message of “Your administrator has made a change to your mailbox. Please restart.” Only Outlook 2007 and higher versions are supported with Exchange 2013.”
$localuser = Get-LocalUser -Name $USERNAME
$localuser | Remove-LocalUser -Confirm:$false
$userprofile = Get-CimInstance -Class Win32_UserProfile | Where-Object { $_.SID -eq $localuser.SID }
$userprofile | Remove-CimInstance -Confirm:$false