Hyper-V replica broker fails to start after being manually shut down

There are numerous suggestions on the web; I found one query on social.technet but even though it was only last night, I’ve lost the url…

Anyway, this query is exactly what fixed it for me. The replica broker was created on DC somedc.mybiz.com. That DC went through a bit of a wobble and was due for decommission anyway, so we demoted it and moved the DC stuff onto a virtual machine.

Turns out that in the registry, there’s a string value somewhere under HKLM\Cluster\Resources\{SOME RANDOM GUID VALUE}\parameters called “CreatingDC”. This was the demoted DC. Edit the value and point it at the new DC – somedc_new.mybiz.com – and the replica broker starts up almost instantly.

UPDATE: Just to satisfy myself that this was the case, I failed the RB over to host 2 (using old DC) and it failed. Modified the above registry key and it started instantly- no reboots or anything.

PowerShell: Retrieve all “live” (pingable) Dell server names, models & serial number

Here’s the other script that filters out anything non-Dell- easy enough to modify so it would focus on any manufacturer (I’ve just noticed that this code would GWMI first, then ping. I’ll change this, otherwise it’ll try to retrieve WMI data from a server it can’t reach.)
=============================================================================
Remove-Item .\Dell_Name_ST_Model.csv

[string]$serverList
[string]$serverArray
[int]$xAxis
[int]$yAxis

$serverList = Get-ADComputer -LDAPFilter “(&(ObjectCategory=Computer)(OperatingSystem=*server*))” | Select-Object Name | Sort-Object Name
$serverNames = $serverList.Name

$serverArray = New-Object ‘object[,]’ $serverList.Count,4
$xAxis = 0
$yAxis = 0

ForEach ($server in $serverNames)
{

$madeBy = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $server | Select-Object Manufacturer -ExpandProperty Manufacturer

If($madeBy -eq “Dell Inc.”)
{
$isAlive = Test-Connection $Server -Count 1 -Quiet
If($isAlive -eq $true)
{
Write-Host “Server $server is fine”
$serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_OperatingSystem -ComputerName $server | Select-Object CSName -ExpandProperty CSName
$yAxis++
$serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $server | Select-Object Manufacturer -ExpandProperty Manufacturer
$yAxis++
$serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $server | Select-Object Model -ExpandProperty Model
$yAxis++
$serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_SystemEnclosure -ComputerName $server | Select-Object SerialNumber -ExpandProperty SerialNumber
}
ElseIf($isAlive -eq $false)
{
Write-Host “Server $server is not responding”
}
}
$yAxis=0
$xAxis++
}

$yAxis=0
$xAxis=0

ForEach($item in $serverArray)
{
$gatherServerArrayContent = $csName = $serverArray[$xAxis,$yAxis]
$gatherServerArrayContent += “,”
$gatherServerArrayContent += $manufacturer = $serverArray[$xAxis,($yAxis+1)]
$gatherServerArrayContent += “,”
$gatherServerArrayContent += $model = $serverArray[$xAxis,($yAxis+2)]
$gatherServerArrayContent += “,”
$gatherServerArrayContent += $serialNumber = $serverArray[$xAxis,($yAxis+3)]

$gatherServerArrayContent | Out-File .\Dell_Name_ST_Model.csv -Append

$yAxis = 0
$xAxis++
}

PowerShell: ping an arbitrary IP subnet

This will ping an arbitrary subnet; feed it an ip range + subnet mask and it will ping all the hosts. Written primarily to handle “hidden” SAN IPs that wouldn’t show up on DHCP.
=======================
Clear-Host #clears the screen, just like CLS does in MS-DOS

#initialises counters to keep track of the various subnet octets. Octet 3 (4th octet) has to be at least 1, so this gets set to 1 regardelss of user input
[int]$counterOctet0 = 0
[int]$counterOctet1 = 0
[int]$counterOctet2 = 0
[int]$counterOctet3 = 1

[int]$singleHostOctet0 = 255
[int]$singleHostOctet1 = 255
[int]$singleHostOctet2 = 255
[int]$singleHostOctet3 = 255

[int]$customIPRange0 = Read-Host -Prompt “Please enter the 1st IP octet”
[int]$customIPRange1 = Read-Host -Prompt “Please enter the 1st IP octet”
[int]$customIPRange2 = Read-Host -Prompt “Please enter the 1st IP octet”
[int]$customIPRange3 = Read-Host -Prompt “Please enter the 1st IP octet”

[int]$customSubnetOctet0 = Read-Host -Prompt “Please enter the 1st subnet octet”
[int]$customSubnetOctet1 = Read-Host -Prompt “Please enter the 2nd subnet octet”
[int]$customSubnetOctet2 = Read-Host -Prompt “Please enter the 3rd subnet octet”
[int]$customSubnetOctet3 = Read-Host -Prompt “Please enter the 4th subnet octet”

$customIPRange3 = $counterOctet3

[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”

$resultOctet0 = $singleHostOctet0 – $customSubnetOctet0
$resultOctet1 = $singleHostOctet1 – $customSubnetOctet1
$resultOctet2 = $singleHostOctet2 – $customSubnetOctet2
$resultOctet3 = $singleHostOctet3 – $customSubnetOctet3

If($resultOctet0 -ne 0)
{
If($resultOctet1 -ne 0)
{
If($resultOctet2 -ne 0)
{
If($resultOctet3 -ne 0)
{
Do
{
Do
{
Do
{
Do
{
$result0 = Test-Connection $ipAddress.IPAddressToString -Quiet
If($result0 -eq $true)
{
Try
{
$hostName = [System.Net.Dns]::GetHostEntry(“$ipAddress”).HostName
}
Catch [system.exception]
{
$hostName = “no host name”
}
Write-Host “The IP Address $ipAddress ($hostName) is responding”
}
ElseIf($result0 -eq $false)
{
Write-Host “The IP Address $ipAddress is not responding”
}
$customIPRange3 = $customIPRange3 + 1
$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange3 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $customIPRange2 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange2 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $counterOctet2
$customIPRange1 = $customIPRange1 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange1 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $counterOctet2
$customIPRange1 = $counterOctet1
$customIPRange0 = $customIPRange0 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange0 -lt 255)
}
Else
{
}
}
Else
{
}
}
Else
{
}
}
ElseIf($resultOctet1 -ne 0)
{
If($resultOctet2 -ne 0)
{
If($resultOctet3 -ne 0)
{
Do
{
Do
{
Do
{
$result1 = Test-Connection $ipAddress.IPAddressToString -Quiet
If($result1 -eq $true)
{
Try
{
$hostName = [System.Net.Dns]::GetHostEntry(“$ipAddress”).HostName
}
Catch [system.exception]
{
$hostName = “no host name”
}
Write-Host “The IP Address $ipAddress ($hostName) is responding”
}
ElseIf($result1 -eq $false)
{
Write-Host “The IP Address $ipAddress is not responding”
}
$customIPRange3 = $customIPRange3 + 1
$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange3 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $customIPRange2 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange2 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $counterOctet2
$customIPRange1 = $customIPRange1 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange1 -lt 255)
}
Else
{
}
}
Else
{
}
}
ElseIf($resultOctet2 -ne 0)
{
If($resultOctet3 -ne 0)
{
Do
{
Do
{
$result2 = Test-Connection $ipAddress.IPAddressToString -Quiet
If($result2 -eq $true)
{
Try
{
$hostName = [System.Net.Dns]::GetHostEntry(“$ipAddress”).HostName
}
Catch [system.exception]
{
$hostName = “no host name”
}
Write-Host “The IP Address $ipAddress ($hostName) is responding”
}
ElseIf($result2 -eq $false)
{
Write-Host “The IP Address $ipAddress is not responding”
}
$customIPRange3 = $customIPRange3 + 1
$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange3 -lt 255)

$customIPRange3 = $counterOctet3
$customIPRange2 = $customIPRange2 + 1
[System.Net.IPAddress]$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange2 -lt 255)
}
Else
{
}
}
ElseIf($resultOctet3 -ne 0)
{
Do
{
$result3 = Test-Connection $ipAddress.IPAddressToString -Quiet
If($result3 -eq $true)
{
Try
{
$hostName = [System.Net.Dns]::GetHostEntry(“$ipAddress”).HostName
}
Catch [system.exception]
{
$hostName = “no host name”
}
Write-Host “The IP Address $ipAddress ($hostName) is responding”
}
ElseIf($result3 -eq $false)
{
Write-Host “The IP Address $ipAddress is not responding”
}
$customIPRange3 = $customIPRange3 + 1
$ipAddress = “$customIPRange0.$customIPRange1.$customIPRange2.$customIPRange3”
}
While ($customIPRange3 -lt 255)
}

PowerShell: Retrieve all “live” (pingable) server names, manufacturers, models & serial number

This script searches AD for any server running Windows Server, strips the names out to make a list, pings the list to avoid wasting time and either gathers some WMI data or reports that the server is offline. It then collates the data for individual servers into one line which it writes to a CSV.

My next script is basically the same thing, but it filters out Dell servers at the start.
=======================================
Remove-Item .\allServers_Name_ST_Model.csv #deletes the old export file
[string]$serverList #this will contain the details of any device running Windows Server in AD
[string]$serverNames
[string]$serverArray #this will contain the name, manufacturer, model and serial number in an array
[int]$xAxis #keeeps track of the vertical array elements
[int]$yAxis #keeps track of the horizontal array elements
$serverList = Get-ADComputer -LDAPFilter "(&(ObjectCategory=Computer)(OperatingSystem=*server*))" | Select-Object Name | Sort-Object Name #Pulls any Windows Servers out of AD
$serverNames = $serverList.Name #Extracts just server names out of $serverList
$serverArray = New-Object 'object[,]' $serverList.Count,4 #creates the array with the same number of lines as there are servers in $serverList, and 4 columns-
#name, manufacturer, model, serial number.
$xAxis = 0 #arrays start at 0!
$yAxis = 0 #arrays start at 0!
ForEach ($server in $serverNames) #starts the loop, cycles through each server in turn
{
$isAlive = Test-Connection $Server -Count 1 -Quiet #creates a variable that will return true/ false depending on wther the server responds
 If($isAlive -eq $true) #if the server responds... pull WMI data from different classes, -ExpandProperty makes the output a bit prettier
 {
 Write-Host "Server $server is fine" #this isn't really necessary, it's handy for manual testing
 $serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_OperatingSystem -ComputerName $server | Select-Object CSName -ExpandProperty CSName
 $yAxis++ #increments $yAxis fro 0 > 1 to access next array element
 $serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $server | Select-Object Manufacturer -ExpandProperty Manufacturer
 $yAxis++ #increments $yAxis fro 1 > 2 to access next array element
 $serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_ComputerSystem -ComputerName $server | Select-Object Model -ExpandProperty Model
 $yAxis++ #increments $yAxis fro 2 > 3 to access next array element (remember 3 is the last column in a 4-column array)
 $serverArray[$xAxis,$yAxis] = Get-WMIObject -Class Win32_SystemEnclosure -ComputerName $server | Select-Object SerialNumber -ExpandProperty SerialNumber
 }
 ElseIf($isAlive -eq $false) #if the server doesn't respond, write the server name with "is not responding" to the array
 {
 $serverArray[$xAxis,$yAxis] = $server
 $yAxis++
 $serverArray[$xAxis,$yAxis] = "is not responding"
 }
 $yAxis=0 #resets the $yAxis so it begins at 0 on the next line
 $xAxis++ #increments $xAxis, this never gets reset to 0 as you just want it to cycle through each server until the end
}

#The $serverArray variable is fully populated by now, so we need to make the data suitable for output
$yAxis=0
$xAxis=0
ForEach($item in $serverArray) #loops through each cell of the array in order to put the collections into comma-separated lines of text
{
 $gatherServerArrayContent = $csName = $serverArray[$xAxis,$yAxis]
 $gatherServerArrayContent += ","
 $gatherServerArrayContent += $manufacturer = $serverArray[$xAxis,($yAxis+1)]
 $gatherServerArrayContent += ","
 $gatherServerArrayContent += $model = $serverArray[$xAxis,($yAxis+2)]
 $gatherServerArrayContent += ","
 $gatherServerArrayContent += $serialNumber = $serverArray[$xAxis,($yAxis+3)]
$gatherServerArrayContent | Out-File .\allServers_Name_ST_Model.csv -Append #each server has it's own line in this file containing the 4 attributes
$yAxis = 0 #same again- reset the $yAxis for the next line
 $xAxis++ #same again- $xAxis never gets reset as it just has to cycle through the whole array
}

0xc0000098 Error PXE booting a client in SCCM 2012 R2

Our SCCM PXE boot system broke recently, and started flagging up the above error code- something about the \tmp\x86x64{…..}.bcd file not containing a valid OS entry for the client.

Went through everything I found on the internet: stopped PXE, watched WDS uninstall, Rename RemoteInstall, start PXE, watch WDS re-install, delete all the boot images, re-import boot images, uninstall ADK8.1, reboot, re-install ADK8.1 etc etc. Nothing, which was getting more and more frustrating.

Turns out… I think either the existing boot images had been corrupted, or the task sequences had lost their link to the boot images, or both.

(1) disable all existing task sequences- just disable so they’re there when things work again;

(2) delete the existing boot images from SCCM, extract known good ADK boot images for x86 and amd64 using copype.cmd;

(3) Re-import these two boot images, alter them so they respond to PXE requests, distribute them to whatever DPs necessary (we only have one SCCM server doing everything). Make sure they are the real ADK boot images- they should only offer a single image, which is WinPE- trying to use an OS Boot image that has a second, Setup image can cause problems;

(4) At this point, PXE should boot but will exit straight away as there are no advertisements- this is a good thing;

(5) pick a task sequence, enable it, right-click it and choose properties, then go to the advanced tab and point it to the right boot image (x64 for a 64-bit OS, x86 for a 32-bit OS);

(6) with a bit of luck, you can boot into WinPE and get your chosen task to display in the menu. If this works, just go around pointing all other task sequences at the correct bit version and re-enable them;

I still have absolutely no idea why this broke- if I hadn’t got way-laid by all the “get-rid-of-PXE-WDS-ADK-and-put-them-back-again-posts” on the internet I might have looked more cautiously first and either spotted the task sequences not having a boot image, or the boot images themselves being corrupt or inappropriate in some way.

It’s really important to get just a single-image WinPE boot WIMs from the ADK; I know you can use and create other WIMs, but I got into a knot where my x64 OS boot WIM insisted on using the Windows setup image in the WIM rather than the WinPE image, and actually wouldn’t let me pick the WinPE image because it told me it was already in use.

This isn’t actually all that big a deal (despite it having just swallowed 3 days of my life): start with clean ADK boot images, and point all your task sequences at one or the other. If I’d known this last Tuesday morning I’d have saved a lot of time.

Unable to move SQL cluster resources to a cluster node

This was really stupid (and easily fixed). I couldn’t move the resources for a clustered SQL server named instance. Turns out, I’d installed the default instance onto the node in question but not the named sequence I needed. Re-run setup on the node, install the named instance and, obviously, everything then worked.