需求:想要购买cvm时初始化数据盘
解决方案:购买cvm的时候,选公共镜像,在cvm购买界面上一并加购数据盘并勾选初始化复选框,然后就会自动化分好区;自定义镜像不行,平台的考虑是:自定义镜像千差万别,平台无法确认客户自定义镜像的init环境,因此前端才没设计那个勾选按钮,不过初始化数据盘本质上是通过init的userdata起作用的,理论上在userdata里传入选公共镜像时勾选初始化数据盘后userdata部分的代码的话,自定义镜像也可以实现初始化数据盘,前提是自定义镜像的init是ok的(linux对应cloudinit,windows对应cloudbase-init)
优化后的windows数据盘初始化代码如下
原本代码里没有匹配上大小是TB的情况,所以大盘不会被初始化,然后我加了匹配大盘的逻辑,把日志输出弄细了些方便出现异常的时候可以回溯定位问题,并增加了≥16TB盘的逻辑:超过16T的盘应该按8192的块大小分区,默认块大小4096最大只能支持到16T分区,超过16TB的那部分空白空间用不上
目前在2008R2、2012R2、2016、2019、2022中文版测试挂20块32000GB的盘进行极限测试是可以顺利初始化的
#ps1
$Global:UserMount = 'E'
$Global:TotalDataDisk = 0
$disks =Get-WmiObject Win32_DiskDrive | Where {$_.Partitions -eq 0} | select DeviceID,Size|findstr /i PHYSICALDRIVE | ForEach-Object { ($_.split("E ")[1].PadLeft(2)) + ',' + ($_.Split(" ")[-1]) }|sort
function SetAllDiskOnline {
Write-Output 'SetAllDiskOnline' >> C:\disk_init.txt
$DiskList = 'list disk' | diskpart.exe
Write-Output $DiskList >> C:\disk_init.txt
foreach ($Disk in $DiskList) {
if ($Disk -match 'Disk\s+(?<DiskIdx>\d+) | \u78c1\u76d8\s+(?<DiskIdx>\d+)') {
$DiskIdx = $Matches.DiskIdx
Write-Output "Setting disk $DiskIdx online" >> C:\disk_init.txt
if ([int]$DiskIdx -ge 1) {
$Global:TotalDataDisk = $Global:TotalDataDisk + 1
$DiskOps = @"
select disk $DiskIdx
online disk
san policy=OnlineAll
exit
"@
$DiskOps | diskpart.exe | Out-Null
Start-Sleep -Seconds 0.1
}
}
}
}
function CheckShouldInit {
Write-Output 'CheckShouldInit' >> C:\disk_init.txt
$VolumeList = 'list volume' | diskpart.exe
$TotalVolume = 0
foreach ($Volume in $VolumeList) {
if ($Volume -match 'Volume\s+(?<VolumeIdx>\d+) | \u5377\s+(?<VolumeIdx>\d+)') {
$TotalVolume = $TotalVolume + 1
}
}
if ($TotalVolume -gt 3) {
Write-Output 'Not a new instance, exit' >> C:\disk_init.txt
exit
}
Write-Output 'New instance to be initilized' >> C:\disk_init.txt
}
function InitDataDisk {
Write-Output 'InitDataDisk' >> C:\disk_init.txt
$DiskList = 'list disk' | diskpart.exe
$DriverLetterList = [char[]](69..90)
$Idx = 0
foreach ($Disk in $DiskList) {
if ($Disk -match 'Disk\s+(?<DiskIdx>\d+)\s+(Online|Offline)\s+(?<Size>\d+)\s+GB\s+(?<Free>\d+)|\u78c1\u76d8\s+(?<DiskIdx>\d+)\s+(\u8054\u673a|\u8131\u673a)\s+(?<Size>\d+)\s+GB\s+(?<Free>\d+)|Disk\s+(?<DiskIdx>\d+)\s+(Online|Offline)\s+(?<Size>\d+)\s+TB\s+(?<Free>\d+)|\u78c1\u76d8\s+(?<DiskIdx>\d+)\s+(\u8054\u673a|\u8131\u673a)\s+(?<Size>\d+)\s+TB\s+(?<Free>\d+)') {
$DiskIdx = $Matches.DiskIdx
if ($DiskIdx -ge 1) {
$DriverLetter = $DriverLetterList[$Idx]
if ($Global:TotalDataDisk -le 1) {
$DriverLetter = $Global:UserMount
}
$disktype="mbr"
if(([Math]::Round($disks[$DiskIdx-1].split(",")[1]/1024/1024/1024)) -gt 2048)
{
$disktype="gpt"
}
$unit=4096
if(([Math]::Round($disks[$DiskIdx-1].split(",")[1]/1024/1024/1024)) -gt 16384)
{
$unit=8192
}
$DiskOps = @"
SELECT DISK $DiskIdx
online disk NOERR
attr disk clear readonly NOERR
convert $disktype NOERR
CREATE PARTITION PRIMARY NOERR
format fs=ntfs unit=$unit quick NOERR
ASSIGN LETTER=$DriverLetter
san policy=onlineall
EXIT
"@
Write-Output "Start initializing disk $DiskIdx" >> C:\disk_init.txt
$DiskOps | diskpart.exe >> C:\disk_init.txt
Start-Sleep -Seconds 0.1
Write-Output "DataDisk $DiskIdx is assigned to driver: $DriverLetter" >> C:\disk_init.txt
$Idx = $Idx + 1
}
}
}
}
Write-Output 'Initializing data disks' >> C:\disk_init.txt
SetAllDiskOnline
CheckShouldInit
InitDataDisk
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。