Microsoft/VMware 製品はこう使う。

好きなことを好きに描く.

搭載しているディスクを綺麗サッパリ初期化してくれるスクリプト(Azure Stack HCI OS, Windows 版 Azure Stack HCI 共通)

こんにちは。

 

前回の記事でAzure Stack HCI OS 21H2 をNested で構築する方法をご紹介しました。

今回は、構築する中で、めちゃくちゃ便利なスクリプトをご紹介します。

 

構築中に あ!間違えた!とか入力ミスして構築をしてしまったことがある人は結構いるとおもいます。構築したあとに フェールオーバークラスタ名が違っていた、とか、
構築に失敗して、ファイルシステムのゴミがいっぱい生まれて、次構築しようとしたらうまく構築ができず四苦八苦、、、などエンジニアのみなさまなら想像がつくかとおもいます。

 

そんなときに使えるスクリプトを 海外のMicrosoft MVP の方が作ってくれていて、これがめちゃくちゃ重宝します。

私のチームではこのスクリプトを "魔法のスクリプト" と呼んでいます 笑

https://github.com/dkawula/Operations/blob/master/S2D/FactoryReset-Clear-SDSConfig.ps1

 

【私が試して動作問題なかったOS】

Windows Server 2019 のS2D
Azure Stack HCI OS 21H2
Azure Stack HCI OS 20H2

 

【ハードウェア環境】
ESXi 上で作成したNested 環境で実行 → 普通に使えた
AX6515(Dell のS2D ReadyNode) → 普通に使えた 
 BOSS Boot Device  240GB x 2 (Raid1)
    SSD 960GB x 4 本(All Flash 構成)

 

想定トラブル時1

実際に私が困って使った状況をご紹介します。
現在、AX6515 というDell Technologiesの S2D Ready Node を使って検証をしているのですが、いざ構成しようとしたら、以前に誰かが使っていてファイルシステムが残っていてこのような状態になっていました。

 

f:id:japan-vmware:20211111121037p:plain

 

これは Get-physicaldisk コマンドレットを実行した結果なのですが、このマシンは SSD 4本とBoot Devce(BOSS)を積んでいるのみのマシンにもかかわらず、過去に誰かが検証した際のゴミが残っています。
OS をインストールするときのセットアップウィザードで消したらいいのでは?という方もいらっしゃるかもしれませんが、残念ながらその画面では消せませんでした。
(状況によりますが)

みて頂くとわかりますが、CanPool 列 が False  になっていますよね。
False になっていると S2D を構成できないのでここを True  にする必要があるわけです。

 

そのため、魔法のスクリプトを実行します。
その前にスクリーンショットの環境は Azure Stack HCI OS 21H2 で実行しているので、Server Core (CLI) のみのOSですので、ネットワーク上に共有ファイルを作って、そこにスクリプトを置いて、ASH OS 側にコピーして実行しました。

172.31.90.5 のCドライブの共有設定して、そこに魔法スクリプトを置いています。
置いた魔法スクリプトを Azue Stack HCI OS の Cドライブ配下にコピーしています。

f:id:japan-vmware:20211111115659p:plain

 

コピーしてきた、スクリプトを実際に実行します。
※元のスクリプト名が長いので 短いスクリプト名に名前変更だけしています。

f:id:japan-vmware:20211111114640p:plain

 

実行開始します。

f:id:japan-vmware:20211111115926p:plain

 

途中で エラーなども多く表示されますが、無視して大丈夫です。
理由は最後に記載します。

f:id:japan-vmware:20211111120011p:plain

 

ディスクがクリーニングされているのがわかります。

f:id:japan-vmware:20211111120144p:plain

 

4本のディスクとBootDevice が削除されていることが表示されています。

f:id:japan-vmware:20211111120251p:plain

 

では実際に、Get−Physicaldisk を実行してみましょう。
ゴミが消えて、SSD 4本とBoot Devce(BOSS) のみ表示されるようになりました。
また、CanPool の値が True になっているので、Azure Stack HCI の構成ができるDisk になっているのがわかります!

f:id:japan-vmware:20211111121359p:plain

 

想定トラブル時2

構築が終わったあとに、再構築する必要がでた場合にも魔法スクリプトは素晴らしい活躍をします 笑

一度2ノードでも、3ノードでもいいのですが、構築し終わったあとの Azure Stack HCI は、フェールオーバークラスタが構成され、S2D(Storage Space Direct)も構成されている状況です。もちろんクラスターが構成されているわけですから、クラスターディスクも作成されているので、再構築になると猛烈にダルい作業が発生します。
エンジニアの人だと「OS再インストールからなのか…?」「ファイルシステムにゴミが残る…」「IP Address 振り直し…?」いろいろ思い浮かぶと思います。

それらの一気に解消するのも魔法スクリプトです。😋

 

先程、ここでエラーがでていましたよね。
ここで何をしているか、というとクラスターの削除やクラスターディスクの削除をしています。

f:id:japan-vmware:20211111120011p:plain

 

つまり、この魔法スクリプトは、クラスターを削除し、S2D 機能をオフにしたのち、
ディスクを綺麗サッパリしてくれるということです。

 

注意点

もし仮想スイッチが作成されている場合は、仮想スイッチだけコマンドで削除する必要があります。そのときは Remove-VMSwitch コマンドレットで削除をお願いします!
コマンドだるいな。。。というときはWindows Admin Centerからホストに接続して仮想スイッチの削除もできます。

最後に

個人的にすばらしいとおもったのは、IP Address の設定は初期化されないですし、ドメインに参加している場合はドメインから離脱することもありません。
つまり、魔法スクリプトを各ノードで実行するだけで再度Azure Stack HCI の構築を開始することができます。
ESXi の Nested とかでここまでの便利なものはみたことが個人的になかったので感動的でした…検証時や実際の構築時に困ったらつかってみてはいかがでしょうか。

一応念の為申し上げておくと、使用については自己責任でお願いしますね😋
Microsoft MVP の方が善意で公開してくれてるものですので。

 

よい Azure Stack HCI 生活を!!!

 

一応スクリプト内容をそのまま張っておきます。

 

-------------------------------------

# #
# *** USE AT YOUR OWN RISK *** #
# PERMANANT DATA LOSS WILL OCCUR #
# #
# This script completely clears any existing Storage Spaces configuration #
# and all data on EVERY non-system drive PERMANENTLY! #
# #
# Notes: #
# #
# If certain drives cannot be cleared and the reason given is #
# 'Redundant Path' then MPIO may need to be installed and/or configured. #
# #
# Power cycling the JBOD enclosures can also remove additional #
# errors encountered during the run. #
# #
# Run cmdlet with Administrator rights. #
# #
################################## WARNING ################################
################################# Change Log ################################
# #
# 02/13/2014: Changed logic to remove SAS-connected boot/system disks #
# 02/13/2014: Changed output for clearing disks and tracking runtime #
# 04/07/2014: Corrected logic to deal boot and system drives #
# 04/07/2014: Added logic to deal with non-core cluster objects #
# 07/23/2015: Changes to better support Storage Spaces Direct #
# #
#############################################################################
#Script has been tested and verified to work to Factory Reset Storage Spaces Direct by Dave Kawula#
[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact="High")]
param()
if ($PSCmdlet.ShouldProcess("localhost","Clear Storage Spaces configuration and wipe disks"))
{
Write-Host ""
Write-Host Clearing existing Storage Spaces configuration and wiping disks...
Write-Host ""
$runStart = [DateTime]::Now
# Install necessary tools if needed
$toolsInstalled = $false
if (!(Get-WindowsFeature -Name "RSAT-Clustering-PowerShell").Installed)
{
Write-Host Installing required tools... -ForegroundColor Cyan -NoNewline
Install-WindowsFeature -Name "RSAT-Clustering-PowerShell"
$toolsInstalled = $true
Write-Host Done.
Write-Host ""
}
# Remove any cluster objects if present
Write-Host "Removing any cluster objects" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
foreach ($clusterGroup in (Get-ClusterGroup -ErrorAction SilentlyContinue -WarningAction SilentlyContinue))
{
if (!$clusterGroup.IsCoreGroup)
{
Remove-ClusterGroup -Name $clusterGroup.Name -Force:$true -RemoveResources:$true -ErrorAction SilentlyContinue
}
}
Remove-Cluster -Force -CleanupAD -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
Write-Host "Done."
$disks = Get-PhysicalDisk | Where-Object {($_.BusType -EQ "SAS") -or ($_.BusType -EQ "SATA")} # -or ($_.BusType -EQ "RAID")}
Write-Host ""
Write-Host "Removing any stale PRs" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
foreach ($disk in $disks)
{
Clear-ClusterDiskReservation -Disk $disk.DeviceId -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
}
Write-Host "Done."
Write-Host ""
Write-Host "Updating the storage provider cache (x2)" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
Update-StorageProviderCache -DiscoveryLevel Full
Start-Sleep 1
Update-StorageProviderCache -DiscoveryLevel Full
Write-Host "Done."
# Remove virtual disks and storage pools
Write-Host ""
Write-Host "Removing Virtual Disks and Pools" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
$storagePools = Get-StoragePool | ? FriendlyName -NE "primordial"
$storagePools | Set-StoragePool -IsReadOnly:$false
Get-VirtualDisk | Set-VirtualDisk -IsManualAttach:$false
Get-VirtualDisk | Remove-VirtualDisk -Confirm:$false
$storagePools | Remove-StoragePool -Confirm:$false
Write-Host "Done."
Write-Host ""
Write-Host "Updating the storage provider cache (x2)" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
Update-StorageProviderCache -DiscoveryLevel Full
Start-Sleep 1
Update-StorageProviderCache -DiscoveryLevel Full
Write-Host "Done."
Write-Host ""
# Collect IDs of any system/boot disks
$disks = Get-Disk
$diskIdsToRemove = @()
foreach ($disk in $disks)
{
if ($disk.IsBoot -or $disk.IsSystem)
{
$diskIdsToRemove += $disk.UniqueId
}
}
# Get collection of physical disks
$allPhysicalDisks = Get-PhysicalDisk | Where-Object {($_.BusType -EQ "SAS") -or ($_.BusType -EQ "SATA")} # -or ($_.BusType -EQ "RAID")}
# Create a new collection of physical disks without any system/boot disks
$physicalDisks = @()
foreach ($physicalDisk in $allPhysicalDisks)
{
$addDisk = $true
foreach ($diskIdToRemove in $diskIdsToRemove)
{
if ($physicalDisk.UniqueId -eq $diskIdToRemove)
{
$addDisk = $false
}
}
if ($addDisk)
{
$physicalDisks += $physicalDisk
}
}
# Iterate through all remaining physcial disks and wipe
Write-Host "Cleaning disks" -ForegroundColor Cyan -NoNewline
Write-Host "..."
$totalDisks = $physicalDisks.Count
$counter = 1
foreach ($physicalDisk in $physicalDisks)
{
$disk = $physicalDisk | Get-Disk
# Make sure disk is Online and not ReadOnly otherwise, display reason
# and continue
$disk | Set-Disk –IsOffline:$false -ErrorAction SilentlyContinue
$disk | Set-Disk –IsReadOnly:$false -ErrorAction SilentlyContinue
# Re-instantiate disks to update changes
$disk = $physicalDisk | Get-Disk
if ($disk.IsOffline -or $disk.IsReadOnly)
{
Write-Host "Warning: " -NoNewline -ForegroundColor Yellow
Write-Host "Unable to process disk " -NoNewline
Write-Host $disk.Number -NoNewline
Write-Host ": Offline Reason: " -NoNewline
Write-Host ($disk.OfflineReason) -NoNewline -ForegroundColor Yellow
Write-Host ", HealthStatus: " -NoNewline
Write-Host $disk.HealthStatus -ForegroundColor Yellow
}
else
{
Write-Host "Cleaning disk " -NoNewline
Write-Host $disk.Number -NoNewline -ForegroundColor Cyan
Write-Host " (" -NoNewline
Write-Host $counter -NoNewline -ForegroundColor Cyan
Write-Host " of " -NoNewline
Write-Host $totalDisks -NoNewline -ForegroundColor Cyan
Write-Host ")..." -NoNewline
# Wipe disk and initialize
$disk | ? PartitionStyle -NE "RAW" | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false
$disk | Initialize-Disk -PartitionStyle GPT
Write-Host Done.
}
$counter++
}
# Remove any installed roles/tools
if ($toolsInstalled)
{
Write-Host Uninstalling Failover Cluster tool... -NoNewline -ForegroundColor Cyan
Remove-WindowsFeature -Name "Failover-Clustering","RSAT-Clustering-PowerShell"
Write-Host Done.
}
Write-Host ""
Write-Host "Updating the storage provider cache (x2)" -NoNewline -ForegroundColor Cyan
Write-Host "..." -NoNewline
Update-StorageProviderCache -DiscoveryLevel Full
Start-Sleep 1
Update-StorageProviderCache -DiscoveryLevel Full
Write-Host "Done."
# Output physical disk counts
Write-Host ""
Write-Host Physical Disks:
Get-PhysicalDisk | Group-Object Manufacturer,Model,MediaType,Size | ft Count,Name -AutoSize
Write-Host Configuration and data cleared!
Write-Host ""
Write-Host "Run duration: " -NoNewline
Write-Host ([Math]::Round((([DateTime]::Now).Subtract($runStart)).TotalMinutes,2)) -ForegroundColor Yellow -NoNewline
Write-Host " minutes"
}