![](https://habrastorage.org/getpro/habr/upload_files/aad/c04/4ad/aadc044ada3d6696755778c71878b96b.png)
Когда нужно массово переустановить ОС на компьютерах в корпоративной сети, мы привыкли использовать System Center Configuration Manager (SCCM) и все хорошо, если речь идёт про Windows, но с Linux немного все сложнее, т.к. нет готовых инструментов в SCCM.
К счастью, SCCM удобный и гибкий инструмент, чтобы решить любую задачу по переустановке ОС. Если у вас инсталляция SCCM не распределённая, где все ПК находятся в одной сети, то вам подойдёт вот эта статья для установки ОС Linux с сетевой папки.
Если у вас распределённая инсталляция SCCM, где много Distribution Point в отдалённых локациях (с «небыстрыми» каналами связи), а установку нужно проводить на 100 ПК одновременно, то с сетевой папки сделать это сложно. Именно эту задачу нам понадобилось решить, попутно улучшив и автоматизировав способ, описанный выше (идея взята из упомянутой статьи и доработана, спасибо fisher51 и моим коллегам, кто помогал).
Итак, приступим.
Создаём виртуалку с минимальным диском, это важно, т.к. от размера будет зависеть размер итогового образа (для Xubuntu достаточно 9Gb). Устанавливаем Xubuntu (для примера), выбирая стандартное разделение дисков:
![Разбивка диска Разбивка диска](https://habrastorage.org/getpro/habr/upload_files/75a/ec6/f9e/75aec6f9e151fa4bc2500e22e33ec75d.png)
Как видно на скриншоте, у нас один диск 9Gb со стандартной разбивкой, где /dev/sda1 – загрузочная партиция (FAT32), /dev/sda2 – логический диск, /dev/sda5 – партиция самого Linux (ext4).
Далее настраиваете операционную систему, как вам нужно, например, в корпоративной среде можно сразу прописать настройки прокси (PAC файл), временную зону и т.д.
Образ можно снять либо на подключённый дополнительный диск, либо подключить сетевой. В последнем случае нам понадобится ещё она компонента:
apt install cifs-utils
Мы помним, что диск у нас уменьшен для минимизации размера образа, но после его разворачивания на обычных компьютерах, где диск более 9Gb, нам нужно его автоматически расширить без привлечения администратора. Также в виде автоматизации можно сделать ввод в домен при запуске системы, либо запуск любых других скриптов, но этот вопрос подробно рассматривать не буду, оставлю для специалистов.
Итак, делаем автоматизацию расширения диска при первом запуске системы.
Создаём/изменяем в директории /etc файл rc.local - это конфиг службы rc-local, которая будет запускаться при запуске системы и стартовать наш/и скрипт/ы.
sudo nano /etc/rc.local
Листинг rc.local
#!/bin/sh -e
exec /usr/sbin/res1.sh
exit 0
где: #!/bin/sh -e - запуск консоли, exec /usr/sbin/res1.sh – запуск скрипта res1.sh
Через команду exec сюда можно дописывать и другие скрипты, главное не забывать их отсюда удалять, иначе они будут запускаться при каждом запуске (хотя это тоже полезно, но не в моем случае).
Делаем этот файл исполняемым chmod +x /etc/rc.local
Создаём в директории /usr/sbin/ файл, называем, например, res1.sh
sudo nano /usr/sbin/res1.sh
Листинг res1.sh
echo -e "resizepart\n2\nYes\n100%\nresizepart\n5\nYes\n100%\nquit" | parted /dev/sda ---pretend-input-tty
echo 1 > /sys/block/sda/device/rescan
resize2fs /dev/sda5
sed -i '/res1.sh/d' /etc/rc.local
rm -f /usr/sbin/res1.sh
reboot
где:
1 строчка – передаём через конвейерный input команду для утилиты parted выполняем resizepart 2 на 100% диска и resizepart 5 на 100% , т.е. раздвигаем логическую и основную партицию linux до 100% диска;
2 строчка – делает обновление информации о диске;
3 строчка – расширяется файловая до конца диска;
4 строчка – удаление строчки запуска скрипта из службы rc.local;
5 строчка – удаление скрипта res1.sh;
6 строчка – перезагрузка.
Делаем этот файл исполняемым: chmod +x /usr/sbin/res1.sh
Я буду снимать образ на сетевой диск, следовательно, подключим его:
mkdir /mnt/image
mount.cifs //имя_сервера/имя_сетевой_папки /mnt/image -o user=имя_пользователя,pass=пароль
Теперь запустим снятие образа на добавленную сетевую папку.
dd if=/dev/sda of=/mnt/image/sda.dd.img bs=8M
где:
if- указываем с какого диска снимаем копию;
of – указываем куда копируем образ;
bs- размер блока чтения 8Мб.
В итоге на сетевой папке у нас лежит образ sda.dd.img размером 9Gb, сжимаем его архиватором 7z, в Zip-файл sda.dd.zip (при выборе максимального сжатия у меня файл получился 2.14 Gb, при минимальном быстром сжатии 2.22 Gb что в целом очень хорошо).
Далее создаём сетевую папку, доступную по всей сети компании, с правами подключения под определённым аккаунтом. В папку выкладываем скрипт SetupLinux.ps1, который будет запускать в Task Sequence с определёнными параметрами.
[CmdletBinding()]
Param(
[Parameter( Mandatory = $true, Position = 0 )]
[ValidateSet( 'ShowProgressLinuxInstall', 'StartShowProgressLinuxInstall', 'CreatePartition', 'SetVariable', 'ShowProgressLinuxDownload', 'StartShowProgressLinuxDownload' )]
[String]$Worktype
)
function Main ( $Worktype ) {
switch ( $Worktype ) {
'CreatePartition' {
$HardDisk = Get-Disk -Number 0
$HardDiskSize = $HardDisk.Size
if ($HardDiskSize -lt 20Gb) {
Write-Host "Small disk, Exit" , $HardDiskSize
Exit 1
}
Get-Disk -Number 0 | Where-Object PartitionStyle -EQ 'RAW' | Initialize-Disk
Write-Host "Initialize Disk complete"
#Start-Sleep -Seconds 5
Get-Disk -Number 0 | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false
Write-Host "Clear Disk complete"
#Start-Sleep -Seconds 5
Get-Disk -Number 0 | Where-Object PartitionStyle -EQ 'RAW' | Initialize-Disk
#Start-Sleep -Seconds 5
Write-Host "Initialize Disk complete"
$Offset = $HardDiskSize-5Gb-10Mb
$NewPartition = Get-Disk -Number 0 | New-Partition -Size 5Gb -Offset $Offset -DriveLetter C
#Start-Sleep -Seconds 5
Write-Host "Create Partition complete"
Format-Volume -FileSystem NTFS -Force -Partition $NewPartition
#Start-Sleep -Seconds 5
Write-Host "Format Partition Disk complete"
}
'StartShowProgressLinuxInstall' {
Start-Process -WindowStyle Hidden -FilePath "powershell.exe" -ArgumentList "-WindowStyle Hidden -NoProfile -nologo -ExecutionPolicy Bypass -File T:\SetupLinux.ps1 -Worktype ShowProgressLinuxInstall"
Exit
}
'ShowProgressLinuxInstall' {
$TsProgressUI = New-Object -ComObject Microsoft.SMS.TsProgressUI
$TotalProgressCount = (Get-Item C:\_SMSTaskSequence\Packages\MVI00424\sda.dd.zip).Length
$CountAttempts = 10
while ($CountAttempts -gt 0) {
Start-Sleep -Seconds 5
$CountAttempts = $CountAttempts - 1
while (Get-WmiObject -Class win32_process -Filter {name = '7z.exe'}) {
$ProgressCount = (Get-WmiObject -Class win32_process -Filter {name = '7z.exe'}).ReadTransferCount
$Procent = $ProgressCount / $TotalProgressCount * 100
$TsProgressUI.ShowTSProgress("","","","Linux Install ($([math]::Round($Procent))% complete)",$Procent,100)
Start-Sleep -Seconds 5
}
}
}
'StartShowProgressLinuxDownload' {
Start-Process -WindowStyle Hidden -FilePath "powershell.exe" -ArgumentList "-WindowStyle Hidden -NoProfile -nologo -ExecutionPolicy Bypass -File T:\SetupLinux.ps1 -Worktype ShowProgressLinuxDownload"
Exit
}
'ShowProgressLinuxDownload' {
$TsProgressUI = New-Object -ComObject Microsoft.SMS.TsProgressUI
$CountAttempts = 10
while ($CountAttempts -gt 0) {
Start-Sleep -Seconds 5
$CountAttempts = $CountAttempts - 1
while (Get-WmiObject -Class win32_process -Filter {name = 'OSDDownloadContent.exe'}) {
$ProgressCount = (Get-WmiObject -Class win32_process -Filter {name = 'OSDDownloadContent.exe'}).ReadTransferCount
$TotalProgressCount = (Get-WmiObject -Class win32_process -Filter {name = 'OSDDownloadContent.exe'}).WriteTransferCount
if ($ProgressCount -gt 1048576) {
$Procent = $ProgressCount / $TotalProgressCount * 100
$TsProgressUI.ShowTSProgress("","","","Download Linux Package ($([math]::Round($Procent))% complete)",$Procent,100)
}
Start-Sleep -Seconds 5
}
}
}
'SetVariable' {
Get-Disk -Number 0 | Update-Disk
Get-Disk -Number 0 | Get-Partition | Where-Object -FilterScript {$_.Type -eq "FAT32"} | Set-Partition -NewDriveLetter C
$TSEnvironment = New-Object -ComObject Microsoft.SMS.TSEnvironment
$config = [PSCustomObject]@{
OSDComputerName = $TSEnvironment.Value("OSDComputerName")
IN_DOMAIN = $TSEnvironment.Value("IN_DOMAIN")
}
Out-File -FilePath C:\config.json -InputObject ($config | ConvertTo-Json) -Encoding utf8
}
}
}
. Main $Worktype
Далее переходим в SCCM и создаём пакет.
![Файлы пакета SCCM Файлы пакета SCCM](https://habrastorage.org/getpro/habr/upload_files/0ad/524/1b4/0ad5241b45413459f712681f18da0873.png)
В пакете у нас должны быть:
7z.dll , 7z.exe - программа 7z, чтобы распаковать архив (достаточно этих файлов);
ddrelease64.exe – утилита DD под Windows, берем отсюда, там есть 32- и 64-битная версия (я использую 64-битную, т.к. у меня boot образ x64);
sda.dd.zip – собственно сам файл архива;
install.cmd – пакетный файл установки.
Листинг install.cmd:
@echo off
cd C:_SMSTaskSequence\Packages\XXX00424
7z.exe e -so sda.dd.zip | ddrelease64.exe of=\?\Device\Harddisk0\Partition0 bs=8M
где:
XXX00424 – код текущего пакета, из которого производится запуск;
C 3 строчкой поясню, распаковываем через 7z в консоль (параметр -so) файл sda.dd.zip. Далее передаём поток утилите ddrelease64.exe и сразу записываем его на диск \\?\Device\Harddisk0\Partition0 блоком 8Mb.
Далее пакет распространяем на Distribution Point’ы.
Теперь создадим загрузочный Task Sequence
![](https://habrastorage.org/getpro/habr/upload_files/1dd/7ea/7c4/1dd7ea7c4be23af9dee03c5f3f82152d.png)
Выбираем Create a new custom task sequence, нажимаем далее.
![](https://habrastorage.org/getpro/habr/upload_files/a91/904/ccf/a91904ccf323281d77071cd75e7c46ad.png)
Выбираем 64-битный загрузочный образ, нажимаем далее.
![](https://habrastorage.org/getpro/habr/upload_files/239/945/e61/239945e6184663a80f5926651bb22c0d.png)
Добавляем шаг 1: перезагрузка, если при запуске задания введён неправильный пароль (защита от «дурака»).
![Шаг 1-Properties Шаг 1-Properties](https://habrastorage.org/getpro/habr/upload_files/077/47e/fdb/07747efdbbac16cb09abf45b128f1eb6.png)
![Шаг 1 - Options Шаг 1 - Options](https://habrastorage.org/getpro/habr/upload_files/022/edd/921/022edd921b7c14189409ce97bf1fb801.png)
Добавляем шаг 2: подключаем сетевую папку, доступную под определённым аккаунтом по всей сети, в которой лежит скрипт SetupLinux.ps1 (описанный выше).
![](https://habrastorage.org/getpro/habr/upload_files/1b2/d91/ed9/1b2d91ed92571670e3092994484cf8fe.png)
Добавляем шаг 3: запуск PowerShell скрипта с параметром -WorkType CreatePartition для инициализации, очистки диска и создания временной NTFS партиции для загрузки образа.
![](https://habrastorage.org/getpro/habr/upload_files/1b9/a48/1e3/1b9a481e3861c323200b52b98891fe25.png)
Добавляем шаг 4: запуск PowerShell скрипта с параметром -WorkType StartShowProgressLinuxDownload для отображения прогресса скачки образа.
![](https://habrastorage.org/getpro/habr/upload_files/6d2/7aa/0fe/6d27aa0fe26fe48e2161b1336e4487a1.png)
Добавляем шаг 5: скачивание пакета SCCM на созданный временный диск NTFS
![](https://habrastorage.org/getpro/habr/upload_files/45d/deb/92e/45ddeb92eceae45d36fd32d36baa9da5.png)
Добавляем шаг 6: запуск PowerShell скрипта с параметром -WorkType StartShowProgressLinuxInstall для отображения прогресса установки образа.
![](https://habrastorage.org/getpro/habr/upload_files/712/85e/e68/71285ee682ce6171d4ea1261668acb08.png)
Добавляем шаг 7: запуск командного файла install.cmd из скачанного на временный диск пакета SCCM.
![](https://habrastorage.org/getpro/habr/upload_files/54b/b58/313/54bb58313815f5e953dc12f8905abfcd.png)
Добавляем шаг 8: запуск PowerShell скрипта с параметром -WorkType SetVariable, в этом шаге на диске, куда уже записали Linux, находим загрузочный диск с FAT32 для сохранения JSON файла с параметрами Task Sequence. Через него можно передать переменные имя компьютера OSDComputerName, нужно ли вводить ПК Linux в домен IN_DOMAIN, либо любые другие параметры. На эту партицию также можно положить любые скрипты, которые вы хотите запустить при запуске ОС Linux.
![](https://habrastorage.org/getpro/habr/upload_files/43e/1a1/e7e/43e1a1e7ecfb2880dd3c292a835ea1db.png)
Далее добавляем Deployment для Task Sequence, указываем необходимые переменные.
![](https://habrastorage.org/getpro/habr/upload_files/244/a57/f0a/244a57f0ad3e666c46a53138e4ff6441.png)
Далее загружаемся по сети PXE и наслаждаемся установкой Linux из SCCM за 5-7 мин.
![](https://habrastorage.org/getpro/habr/upload_files/465/a75/3de/465a753de45a1a941ef1162dd167fc81.png)
![](https://habrastorage.org/getpro/habr/upload_files/c95/5c6/58e/c955c658e40814045f6b67b51eeffd88.png)
![](https://habrastorage.org/getpro/habr/upload_files/26f/bbf/0f7/26fbbf0f7e57e8123c168c5ca88bc636.png)
![](https://habrastorage.org/getpro/habr/upload_files/38d/d0b/348/38dd0b348eccd8778aff963790e1139e.png)
![](https://habrastorage.org/getpro/habr/upload_files/9b8/013/9a2/9b80139a2ab255c45b157fd5f3fb4ba8.png)
![](https://habrastorage.org/getpro/habr/upload_files/a2a/d3f/1ec/a2ad3f1ec0da51c0e153d2aecda811df.png)
![](https://habrastorage.org/getpro/habr/upload_files/b56/507/eec/b56507eec3820e6a7c85483a3bd1fbd7.png)
В итоге получилась заливка ОС Linux и партиция раздвинута до конца диска 40gb.
![](https://habrastorage.org/getpro/habr/upload_files/9ec/995/db8/9ec995db8d7079402191816c8c6b250c.png)
Чтобы убедится, что мы передали файл конфига из SCCM в Linux, подключим временно партицию /dev/sda1, командой mount /dev/sda1 /mnt/cm
![](https://habrastorage.org/getpro/habr/upload_files/97e/5a9/b51/97e5a9b51180864c4025ad9a2c39eb27.png)
Параметры, переданные через JSON из Task Sequence:
![](https://habrastorage.org/getpro/habr/upload_files/394/8bf/a9b/3948bfa9befc532b56529f9c529fd632.png)
Вот и все, наслаждаемся работой Linux в корпоративной сети.
Удачи вам в ваших экспериментах.
Комментарии (19)
onegreyonewhite
08.06.2022 13:18+4А чем Cobbler не подошёл? Он ещё и репы в себе может держать (и обновлять), установка и настройка через кикстарт и подобные. Тот же Ubuntu MAAS тоже можно, но это больше про сервера. Зачем насиловать форточками пингвина?
sarksiov79 Автор
08.06.2022 14:18Ну если делать вообще с нуля, то им тоже можно, вариантов много, тут накинул.
Но если уже в сети развернут SCCM с DP, зачем переделывать PXE точки?
В схеме с SCCM, можно будет ставить оба вида операционок, кому-то форточки, а кому-то пингвинов.
Cruz_Castillo
08.06.2022 18:00Коллега, а не пробовали классический автоматизированный сценарий "обновления" ОС (что раньше описывался в методике BDD - Business Desktop Deployment как Zero Touch Installation)? Сбор данных/пользовательских файлов (Windows, USMT без шифрования, в сеть); ребут (WPE), форматирование, образ (Linux); восстановление данных (из сети). PXE не нужен, начало процесса - SCCM client. К тому, что массовые миграции из одной точки с Windows на Linux не за горами.
sarksiov79 Автор
08.06.2022 18:03Для Windows использовали, но для Linux нет, хотя проблемы не вижу, сценарий примерно такой же.
Alexrook
08.06.2022 13:43+1Можете пояснить, если мы меняем одну зарубежную ОС на другую зарубежную ОС, при чем здесь термин «Импортозамещение»?
sarksiov79 Автор
08.06.2022 14:22+1У меня был кейс с xubuntu, но таким же способом можно ставить любой дистрибутив Linux, хоть Альт.
Kagato_by
08.06.2022 20:29Альт внезапно перестал быть зарубежным потому что кто-то внутри страны его собирает из чужих сорсов?
Francyz
08.06.2022 15:03+2Раз уж на то пошло, то и SCCM нужно будет скоро импортозамещать, так что статья актуальна до поры до времени.
amarao
08.06.2022 14:34+4У линукса есть масса интересных решений для разворачивания бареметалла. Начиная от скромных pxe-серверов с которых можно "забутиться и раскатать" и заканчивая боевыми мультитенантными ironic'ами.
Количество прогресс-баров и окошек в этой штуке меня сильно напрягло. так же как и количество винды. Может, лучше, без всё-таки?
С точки же зрения разворачивания серверов - доставка образа - это относительно сложная, но ограниченная задача. Вот финальное конфигурирование (сеть, имя, ssh-ключи, пользователи) - это куда более тонко. (подсказка Cloud Init, datasource=NoCloud).
sarksiov79 Автор
08.06.2022 18:09Решений согласен масса, тут описан метод, если в компании уже есть большая инфраструктура SCCM. Кончено, специально его ставить, для это задачи не нужно.
AAT666
08.06.2022 17:58+1Спасибо большое за инструкцию! Оччччень пригодится вскорости!
Но судя по всему - все данные пользовател-я(ей) (как в профилях, так и просто на разделах диска) надо как-то куда-то заранее сохранить ?..
sarksiov79 Автор
08.06.2022 18:06Коллега выше в комментариях написал, можно прикрутить USMT и сохранить данные.
AAT666
08.06.2022 20:03Ну, "прикручивать" ничего не надо - MECM умеет это делать "из коробки", как по hardlink - так и в точку миграции... Интересовал, именно, момент переноса данных. Но, я так понял, это не входило в Вашу задачу... Но опыт - очень интересный! Благодарю еще раз!
alef13
08.06.2022 22:19+1вот что бывает когда поручают импортозамещение любителям винды :) не в обиду, но действительно - есть штатные средства развёртывания и намного удобнее и проще чем раскатка образа, который потом ещё допиливать и допиливать. И полагаю что это будет традиционно мышкой в сессии vnc с обязательным присутствием пользователя
polar_yogi
09.06.2022 14:44>Через команду exec сюда можно дописывать и другие скрипты,
Я, возможно, зануда... Нет, не так.
Я знаю, что я зануда, но команда exec запускает выполнение программы, заменяя родительский процесс, поэтому все команды после первого exec выполнены не будут.
ky0
Выглядит сложновато по сравнению с конфигом в 20 строчек в Терраформе, разворачивающим всё нужное из шаблона.
sarksiov79 Автор
Терраформ применим, на виртуалках в ЦОДе, а тут задача кучу виндовых тачек перезалить на обычных ПК.
ky0
Возможно, я недостаточно внимательно читал — но каков кейс сего действа? На первый взгляд похоже на разовую задачу.
dbax
ansible?