Добавлена папка source в CristalDiskMark
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
<#
|
||||
DISKSPD - VM Fleet
|
||||
|
||||
Copyright(c) Microsoft Corporation
|
||||
All rights reserved.
|
||||
|
||||
MIT License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
#>
|
||||
|
||||
param(
|
||||
[string]$BaseVHD = $(throw "please specify a base vhd"),
|
||||
[int]$VMs = $(throw "please specify a number of vms per node csv"),
|
||||
[string[]]$Groups = @(),
|
||||
[string]$AdminPass = $(throw 'need admin password for autologin'),
|
||||
[string]$Admin = 'administrator',
|
||||
[string]$ConnectPass = $(throw 'need password for loopback host connection'),
|
||||
[string]$ConnectUser = $(throw 'need username for loopback host connection'),
|
||||
[validateset('CreateVMSwitch','CopyVHD','CreateVM','CreateVMGroup','AssertComplete')][string]$StopAfter,
|
||||
[validateset('Force','Auto','None')][string]$Specialize = 'Auto',
|
||||
[switch]$FixedVHD = $true,
|
||||
[string[]]$Nodes = @()
|
||||
)
|
||||
|
||||
function Stop-After($step)
|
||||
{
|
||||
if ($stopafter -eq $step) {
|
||||
write-host -ForegroundColor Green Stop after $step
|
||||
return $true
|
||||
}
|
||||
return $false
|
||||
}
|
||||
|
||||
##################
|
||||
|
||||
# validate existence of basevhd
|
||||
if (!(test-path -path $BaseVHD)) {
|
||||
throw "Base VHD $BaseVHD not found"
|
||||
}
|
||||
|
||||
if (Get-ClusterNode |? State -ne Up) {
|
||||
throw "not all cluster nodes are up; please address before creating vmfleet"
|
||||
}
|
||||
|
||||
# if no nodes specified, use the entire cluster
|
||||
if ($nodes.count -eq 0) {
|
||||
$nodes = Get-ClusterNode
|
||||
}
|
||||
|
||||
# convert to fixed vhd(x) if needed
|
||||
if ((get-vhd $basevhd).VhdType -ne 'Fixed' -and $fixedvhd) {
|
||||
|
||||
# push dynamic vhd to tmppath and place converted at original
|
||||
# note that converting a dynamic will leave a sparse hole on refs
|
||||
# this is OK, since the copy will not copy the hole
|
||||
$f = gi $basevhd
|
||||
$tmpname = "tmp-$($f.Name)"
|
||||
$tmppath = join-path $f.DirectoryName $tmpname
|
||||
del -Force $tmppath -ErrorAction SilentlyContinue
|
||||
ren $f.FullName $tmpname
|
||||
|
||||
write-host -ForegroundColor Yellow "convert $($f.FullName) to fixed via $tmppath"
|
||||
convert-vhd -Path $tmppath -DestinationPath $f.FullName -VHDType Fixed
|
||||
if (-not $?) {
|
||||
ren $tmppath $f.Name
|
||||
throw "ERROR: could not convert $($f.fullname) to fixed vhdx"
|
||||
}
|
||||
|
||||
del $tmppath
|
||||
}
|
||||
|
||||
# Create the fleet vmswitches with a fixed IP at the base of the APIPA range
|
||||
icm $nodes {
|
||||
|
||||
if (-not (Get-VMSwitch -Name Internal -ErrorAction SilentlyContinue)) {
|
||||
|
||||
New-VMSwitch -name Internal -SwitchType Internal
|
||||
Get-NetAdapter |? DriverDescription -eq 'Hyper-V Virtual Ethernet Adapter' |? Name -eq 'vEthernet (Internal)' | New-NetIPAddress -PrefixLength 16 -IPAddress '169.254.1.1'
|
||||
}
|
||||
} | ft -AutoSize
|
||||
|
||||
#### STOPAFTER
|
||||
if (Stop-After "CreateVMSwitch") {
|
||||
return
|
||||
}
|
||||
|
||||
# create $vms vms per each csv named as <nodename><group prefix>
|
||||
# vm name is vm-<group prefix><$group>-<hostname>-<number>
|
||||
|
||||
icm $nodes -ArgumentList $stopafter,(Get-Command Stop-After) {
|
||||
|
||||
param( [string]$stopafter,
|
||||
$fn )
|
||||
|
||||
set-item -Path function:\$($fn.name) -Value $fn.definition
|
||||
# workaround evaluation bug and make $stopafter evaluate in the session
|
||||
$null = $stopafter
|
||||
|
||||
function apply-specialization( $path )
|
||||
{
|
||||
# all steps here can fail immediately without cleanup
|
||||
|
||||
# error accumulator
|
||||
$ok = $true
|
||||
|
||||
# create run directory
|
||||
|
||||
del -Recurse -Force z:\run -ErrorAction SilentlyContinue
|
||||
mkdir z:\run
|
||||
$ok = $ok -band $?
|
||||
if (-not $ok) {
|
||||
Write-Error "failed run directory creation for $vhdpath"
|
||||
return $ok
|
||||
}
|
||||
|
||||
# autologon
|
||||
$null = reg load 'HKLM\tmp' z:\windows\system32\config\software
|
||||
$ok = $ok -band $?
|
||||
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultUserName /t REG_SZ /d $using:admin
|
||||
$ok = $ok -band $?
|
||||
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v DefaultPassword /t REG_SZ /d $using:adminpass
|
||||
$ok = $ok -band $?
|
||||
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v AutoAdminLogon /t REG_DWORD /d 1
|
||||
$ok = $ok -band $?
|
||||
$null = reg add 'HKLM\tmp\Microsoft\Windows NT\CurrentVersion\WinLogon' /f /v Shell /t REG_SZ /d 'powershell.exe -noexit -command c:\users\administrator\launch.ps1'
|
||||
$ok = $ok -band $?
|
||||
$null = [gc]::Collect()
|
||||
$ok = $ok -band $?
|
||||
$null = reg unload 'HKLM\tmp'
|
||||
$ok = $ok -band $?
|
||||
if (-not $ok) {
|
||||
Write-Error "failed autologon injection for $vhdpath"
|
||||
return $ok
|
||||
}
|
||||
|
||||
# scripts
|
||||
|
||||
copy -Force C:\ClusterStorage\collect\control\master.ps1 z:\run\master.ps1
|
||||
$ok = $ok -band $?
|
||||
if (-not $ok) {
|
||||
Write-Error "failed injection of specd master.ps1 for $vhdpath"
|
||||
return $ok
|
||||
}
|
||||
|
||||
del -Force z:\users\administrator\launch.ps1 -ErrorAction SilentlyContinue
|
||||
gc C:\ClusterStorage\collect\control\launch-template.ps1 |% { $_ -replace '__CONNECTUSER__',$using:connectuser -replace '__CONNECTPASS__',$using:connectpass } > z:\users\administrator\launch.ps1
|
||||
$ok = $ok -band $?
|
||||
if (-not $ok) {
|
||||
Write-Error "failed injection of launch.ps1 for $vhdpath"
|
||||
return $err
|
||||
}
|
||||
|
||||
echo $vmspec > z:\vmspec.txt
|
||||
$ok = $ok -band $?
|
||||
if (-not $ok) {
|
||||
Write-Error "failed injection of vmspec for $vhdpath"
|
||||
return $ok
|
||||
}
|
||||
|
||||
# load files
|
||||
$f = 'z:\run\testfile1.dat'
|
||||
if (-not (gi $f -ErrorAction SilentlyContinue)) {
|
||||
fsutil file createnew $f (10GB)
|
||||
$ok = $ok -band $?
|
||||
fsutil file setvaliddata $f (10GB)
|
||||
$ok = $ok -band $?
|
||||
}
|
||||
if (-not $ok) {
|
||||
Write-Error "failed creation of initial load file for $vhdpath"
|
||||
return $ok
|
||||
}
|
||||
|
||||
return $ok
|
||||
}
|
||||
|
||||
function specialize-vhd( $vhdpath )
|
||||
{
|
||||
$vhd = (gi $vhdpath)
|
||||
$vmspec = $vhd.Directory.Name,$vhd.BaseName -join '+'
|
||||
|
||||
# mount vhd and its largest partition
|
||||
$o = Mount-VHD $vhd -NoDriveLetter -Passthru
|
||||
if ($o -eq $null) {
|
||||
Write-Error "failed mount for $vhdpath"
|
||||
return $false
|
||||
}
|
||||
$p = Get-Disk -number $o.DiskNumber | Get-Partition | sort -Property size -Descending | select -first 1
|
||||
$p | Add-PartitionAccessPath -AccessPath Z:
|
||||
|
||||
$ok = apply-specialization Z:
|
||||
|
||||
Remove-PartitionAccessPath -AccessPath Z: -InputObject $p
|
||||
Dismount-VHD -DiskNumber $o.DiskNumber
|
||||
|
||||
return $ok
|
||||
}
|
||||
|
||||
$csvs = Get-ClusterSharedVolume
|
||||
|
||||
# handle restore cases by mapping the csv to the friendly name of the volume
|
||||
# don't rely on the csv name to contain this data
|
||||
|
||||
$vh = @{}
|
||||
Get-Volume |? FileSystem -eq CSVFS |% { $vh[$_.Path] = $_ }
|
||||
|
||||
$csvs |% {
|
||||
$v = $vh[$_.SharedVolumeInfo.Partition.Name]
|
||||
if ($v -ne $null) {
|
||||
$_ | Add-Member -NotePropertyName VDName -NotePropertyValue $v.FileSystemLabel
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($csv in $csvs) {
|
||||
|
||||
if ($($using:groups).Length -eq 0) {
|
||||
$groups = @( 'base' )
|
||||
} else {
|
||||
$groups = $using:groups
|
||||
}
|
||||
|
||||
# identify the CSvs for which this node should create its VMs
|
||||
# the trailing characters (if any) are the group prefix
|
||||
if ($csv.VDName -match "^$env:COMPUTERNAME(?:-.+){0,1}") {
|
||||
|
||||
foreach ($group in $groups) {
|
||||
|
||||
if ($csv.VDName -match "^$env:COMPUTERNAME-([^-]+)$") {
|
||||
$g = $group+$matches[1]
|
||||
} else {
|
||||
$g = $group
|
||||
}
|
||||
|
||||
foreach ($vm in 1..$using:vms) {
|
||||
|
||||
$stop = $false
|
||||
|
||||
$newvm = $false
|
||||
$name = "vm-$g-$env:COMPUTERNAME-$vm"
|
||||
$path = Join-Path $csv.SharedVolumeInfo.FriendlyVolumeName $name
|
||||
|
||||
# place vhdx in subdirectory, per scvmm layout defaults
|
||||
# $vhd = $path+".vhdx"
|
||||
$vhd = join-path $path "$name.vhdx"
|
||||
|
||||
# if the vm cluster group exists, we are already deployed
|
||||
if (-not (Get-ClusterGroup -Name $name -ErrorAction SilentlyContinue)) {
|
||||
|
||||
if (-not $stop) {
|
||||
$stop = Stop-After "AssertComplete"
|
||||
}
|
||||
|
||||
if ($stop) {
|
||||
|
||||
Write-Host -ForegroundColor Red "vm $name not deployed"
|
||||
|
||||
} else {
|
||||
|
||||
Write-Host -ForegroundColor Yellow "create vm $name @ metadata path $path with vhd $vhd"
|
||||
|
||||
# create vm if not already done
|
||||
# note that when restarting interrupted creation, the vm could have moved elsewhere
|
||||
# under cluster control.
|
||||
|
||||
$o = Get-ClusterGroup |? GroupType -eq VirtualMachine |? Name -eq $name
|
||||
|
||||
if (-not $o) {
|
||||
|
||||
# force re-specialization
|
||||
$newvm = $true
|
||||
|
||||
# if the cluster group doesn't exist, we're on the canonical node to create the vm
|
||||
# if the vm exists, tear it down and refresh
|
||||
|
||||
$o = get-vm -Name $name -ErrorAction SilentlyContinue
|
||||
|
||||
if ($o) {
|
||||
|
||||
# interrupted between vm creation and role creation; redo it
|
||||
write-host "REMOVING vm $name for re-creation"
|
||||
|
||||
if ($o.State -ne 'Off') {
|
||||
Stop-VM -Name $name -Force -Confirm:$false
|
||||
}
|
||||
Remove-VM -Name $name -Force -Confirm:$false
|
||||
|
||||
} else {
|
||||
|
||||
# scrub and re-create the vm metadata path and vhd
|
||||
rmdir -ErrorAction SilentlyContinue -Recurse $path
|
||||
$null = mkdir -ErrorAction SilentlyContinue $path
|
||||
|
||||
cp $using:basevhd $vhd
|
||||
}
|
||||
|
||||
#### STOPAFTER
|
||||
if (-not $stop) {
|
||||
$stop = Stop-After "CopyVHD"
|
||||
}
|
||||
|
||||
if (-not $stop) {
|
||||
$o = New-VM -VHDPath $vhd -Generation 2 -SwitchName Internal -Path $path -Name $name
|
||||
|
||||
# create A1 VM. use set-vmfleet to alter fleet sizing post-creation.
|
||||
$o | Set-VM -ProcessorCount 1 -MemoryStartupBytes 1.75GB -StaticMemory
|
||||
|
||||
# do not monitor the internal switch connection; this allows live migration
|
||||
$o | Get-VMNetworkAdapter| Set-VMNetworkAdapter -NotMonitoredInCluster $true
|
||||
}
|
||||
}
|
||||
|
||||
#### STOPAFTER
|
||||
if (-not $stop) {
|
||||
$stop = Stop-After "CreateVM"
|
||||
}
|
||||
|
||||
if (-not $stop) {
|
||||
|
||||
# create clustered vm role and assign default owner node
|
||||
$o | Add-ClusterVirtualMachineRole
|
||||
Set-ClusterOwnerNode -Group $o.VMName -Owners $env:COMPUTERNAME
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
Write-Host -ForegroundColor Green "vm $name already deployed"
|
||||
}
|
||||
|
||||
#### STOPAFTER
|
||||
if (-not $stop) {
|
||||
$stop = Stop-After "CreateVMGroup"
|
||||
}
|
||||
|
||||
if (-not $stop -or ($using:specialize -eq 'Force')) {
|
||||
# specialize as needed
|
||||
# auto only specializes new vms; force always; none skips it
|
||||
if (($using:specialize -eq 'Auto' -and $newvm) -or ($using:specialize -eq 'Force')) {
|
||||
write-host -fore yellow specialize $vhd
|
||||
if (-not (specialize-vhd $vhd)) {
|
||||
write-host -fore red "Failed specialize of $vhd, halting."
|
||||
}
|
||||
} else {
|
||||
write-host -fore green skip specialize $vhd
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user