Scripts/Export-HpcConfiguration.ps1 (193 lines of code) (raw):

<# .SYNOPSIS Export Windows HPC Cluster Configuration Settings. .DESCRIPTION This script allows a user to export Windows HPC cluster configuration settings. .PARAMETER Path The export destination path. .PARAMETER Configuration The name of the configuration settings to export. Valid values: "Diagnostics","Management","Reporting","Scheduler","Soa" or none for all configurations. .PARAMETER DontAppendTimeStampFolder The flag to turn off creating a sub folder in the given path. .EXAMPLE Export-HpcConfiguration.ps1 .EXAMPLE Export-HpcConfiguration.ps1 -Path:c:\export -Configuration:Scheduler .EXAMPLE Export-HpcConfiguration.ps1 -Path:c:\export -DontAppendTimeStampFolder .EXAMPLE Export-HpcConfiguration.ps1 -Path:c:\export -Configuration:Scheduler,Soa .NOTES .LINK #> Param( [switch] $DontAppendTimeStampFolder, # The export destination path. [ValidateNotNullOrEmpty()] [string] $Path, # The names of the configuration settings to export. Valid values: "Diagnostics","Management","Reporting","Scheduler","Soa" or none for all configurations. [ValidateSet("Diagnostics","Management","Reporting","Scheduler","Soa")] [string[]] $Configuration ) function PreExportItem( [string] $Name, [string] $Target, [bool] $IsFolder) { WriteOutput ("Exporting $Name to $Target."); $Global:OldErrorCount = $Global:Error.Count; $Global:WarningForCmdlet = $null; $Global:Xml += '<ExportedConfiguration Name="' + $Name + '" Target="' + $Target + '" />'; if ( !$IsFolder ) { $Target = [System.IO.Path]::GetDirectoryName($Target); } if( !(Test-Path $Target) ) { New-Item -Path $Target -ItemType directory | out-null; } } function PostExportItem { if( $Global:Error.Count -gt $Global:OldErrorCount ) { $Global:FailureCount++; } else { $Global:SuccessCount++; } $Global:WarningForCmdlet | ? { $_ -ne $null } | % { $Global:Warning += "WARNING: " + $_.Message + [environment]::NewLine + [environment]::NewLine; $Global:Verbose += "WARNING: " + $_.Message + [environment]::NewLine + [environment]::NewLine; } } function WriteWarning( [string] $warning) { Write-Warning $warning; $Global:Warning += "WARNING: $warning" + [environment]::NewLine + [environment]::NewLine; $Global:Verbose += "WARNING: $warning" + [environment]::NewLine + [environment]::NewLine; } function WriteOutput( [string] $output) { Write-Output $output; $Global:Verbose += $output + [environment]::NewLine + [environment]::NewLine; } $error.Clear(); $errorMsgNonElevatedProcess = "This function needs to be run with elevated PowerShell."; $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent() ); if(!$currentPrincipal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator )) { Write-Error $errorMsgNonElevatedProcess; return; } $errorMsgCannotOnlyRunOnHeadNode = "This function needs to be run on head node."; if( !(Test-Path HKLM:\Software\Microsoft\HPC) -or (Get-ItemProperty -Path:HKLM:\Software\Microsoft\HPC).InstalledRole -inotcontains "HN") { Write-Error $errorMsgCannotOnlyRunOnHeadNode; return; } if( !(Get-PsSnapIn Microsoft.HPC -EA:0) ) { Add-PsSnapIn Microsoft.HPC; } $error.Clear(); if ([string]::IsNullOrEmpty($path)) { if ($DontAppendTimeStampFolder) { # The script will surely fail $errorMsgNeedPathParam = "-DontAppendTimeStampFolder switch is specified, while -Path parameter is missing. Please include the path information in the parameter list. The folder indicated by the path will be created by this script."; Write-Error $errorMsgNeedPathParam; return; } # Assign path as current folder. $Path = "."; } if (!$DontAppendTimeStampFolder) { $Path = [System.IO.Path]::Combine($Path, [System.DateTime]::Now.ToString("yyyyMMdd_HHmmss")); } $errorMsgCannotCreateTargetFolder = "Cannot create exporting target folder ""$Path"". The directory already exists or the given path is invalid."; # We only work with path which does not exist. This prevents data over-writing handling if ([System.IO.Directory]::Exists($Path)){ Write-Error $errorMsgCannotCreateTargetFolder; return; } [System.IO.Directory]::CreateDirectory($path) | out-null; # We need to ensure the created path is a disk IO object and the CreateDirectory function completes successfully # CreateDirectory won't create folder in registry # CreateDirectory may fail for invalid path or bad permission. if( (Get-ItemProperty $Path) -eq $null -or (Get-ItemProperty $Path).GetType().Name -ne "DirectoryInfo") { Write-Error $errorMsgCannotCreateTargetFolder; return; } $Path = [System.IO.Path]::GetFullPath($Path); WriteOutput("Setting exporting target folder to ""$Path""."); if($Configuration -eq $null) { $Configuration = "Diagnostics","Management","Reporting","Scheduler","Soa"; } $version = (Get-HpcClusterOverview).Version; if( $error ) { return; } $Global:SuccessCount = $Global:FailureCount = 0; $Global:Warning = $Global:Verbose = ""; $Global:Xml = '<?xml version="1.0" encoding="utf-8"?><!-- Note:Changing ExportedConfiguration element in this file will not impact the behavior of Import-HpcConfiguration later. --><ExportedConfigurations HpcVersion="' + $version + '" ClusterName="' + $Env:CCP_SCHEDULER + '" Time="' + [System.DateTime]::Now.ToString() + '" CmdLine="' + $MyInvocation.Line + '" Operator="' + $Env:USERDOMAIN + '\' + $Env:USERNAME + '">'; $redirectToExportFolderCfg = "ActivationFilterProgram", "SubmissionFilterProgram"; $bypassCfg = "ActivationFilterProgram","AdFailurePercentageEntry","BackfillLoadPeriod","DisableCredentialReuse","EmailCredential","EventListenerClosePercentage","InstallCredential","RestoreMode","SchedulerOnAzure","SchedulerWebServicePort","SchedulerWebServiceEnabled","SchedulerWebServiceThumbprint","SchedulerWebServiceAuth","SpoolDir","SqlReadFailurePercentageEntry","SqlTransactionFailurePercentage","SubmissionFilterProgram","ReportingDbSize"; $bypassSchdEnvVar = "CCP_CLUSTER_NAME","CCP_MPI_NETMASK","CCP_SERVICEREGISTRATION_PATH","WCF_NETWORKPREFIX"; $diagCfgNames = "TtlCompletedRuns","RunCleanUpHour","ConcurrencyTestRunNumber"; $mgmtCfgNames = "AzureCollectionInterval","CollectCounters","MinuteCounterRetention","NodeNamingSeries","WDSMode","InstallCredential","AzureStorageConnectionString", "AzureLogsToBlob", "AzureLogsToBlobThrottling", "AzureLogsToBlobInterval", "AzureMetricsCollectionEnabled","AzureMetricsJobStatisticsDelayMinutes","AzureIaaSMetricsCollectionEnabled","OperationArchive","OperationRetention"; $rptCfgNames = "DataExtensibilityEnabled","DataExtensibilityTtl","AllocationHistoryTtl","ReportingDbSize"; if($Configuration -icontains "Management") { PreExportItem -Name:"Cluster registry" -Target:"$Path\ClusterRegistry.xml" -IsFolder:$false; Get-HpcClusterRegistry | Export-CliXml -Path "$Path\ClusterRegistry.xml"; PostExportItem; } if($Configuration -icontains "Diagnostics") { PreExportItem -Name:"diagnostics configurations" -Target:"$Path\Diagnostics" -IsFolder:$true; Get-HpcClusterProperty -Parameter -WA:SilentlyContinue | ? {$diagCfgNames -icontains $_.Name -and $bypassCfg -inotcontains $_.Name} | Export-CliXml -Path "$Path\Diagnostics\DiagnosticsCfg.xml"; PostExportItem; } if($Configuration -icontains "Management") { $installShare = (Get-HpcClusterRegistry -PropertyName InstallShare).Value PreExportItem -Name:"drivers" -Target:"$Path\Management\HpcDriver" -IsFolder:$true; if( Test-Path "$installShare\Drivers" ) { Copy-Item "$installShare\Drivers\*" "$Path\Management\HpcDriver" -Recurse | out-null; } PostExportItem; PreExportItem -Name:"images" -Target:"$Path\Management\HpcImage" -IsFolder:$true; if ( Test-Path "$installShare\Images") { Copy-Item "$installShare\Images\*" "$Path\Management\HpcImage" -Recurse | out-null; } PostExportItem; PreExportItem -Name:"users" -Target:"$Path\Management\HpcUser.xml" -IsFolder:$false; Get-HpcMember -WV:+Global:WarningForCmdlet | ? { !($_.Name.EndsWith("$")) } | Export-Clixml -Path "$Path\Management\HpcUser.xml"; WriteWarning "Machine accounts are not exported as HPC users for security reason."; PostExportItem; PreExportItem -Name:"node groups" -Target:"$Path\Management\HpcNodeGroup.xml" -IsFolder:$false; Get-HpcGroup -WV:+Global:WarningForCmdlet | Export-Clixml -Path "$Path\Management\HpcNodeGroup.xml"; PostExportItem; PreExportItem -Name:"node templates" -Target:"$Path\Management\HpcNodeTemplate" -IsFolder:$true; Get-HpcNodeTemplate -WV:+Global:WarningForCmdlet | % { if( $_.Name -ne "HeadNode Template" –and $_.Name –ne "LinuxNode Template" –and $_.Name –ne "NonDomain ComputeNode Template" -and $_.Name -ne "Default ComputeNode Template") { Export-HpcNodeTemplate -Template $_ -Path "$Path\Management\HpcNodeTemplate\$($_.Name).xml" -WV:+Global:WarningForCmdlet; } }; PostExportItem; PreExportItem -Name:"management configurations" -Target:"$Path\Management\ManagementCfg.xml" -IsFolder:$false; Get-HpcClusterProperty -WV:+Global:WarningForCmdlet | ? {$mgmtCfgNames -icontains $_.Name -and $bypassCfg -inotcontains $_.Name} | Export-CliXml -Path "$Path\Management\ManagementCfg.xml"; PostExportItem; PreExportItem -Name:"hpc metrics" -Target:"$Path\Management\Metrics.xml" -IsFolder:$false; Export-HpcMetric -Path "$Path\Management\Metrics.xml"; PostExportItem; PreExportItem -Name:"hpc nodes" -Target:"$Path\Management\HpcNode.xml" -IsFolder:$false; Export-HpcNodeXml -Path "$Path\Management\HpcNode.xml"; PostExportItem; } if($Configuration -icontains "Reporting") { PreExportItem -Name:"reporting configurations" -Target:"$Path\Reporting" -IsFolder:$true; Get-HpcClusterProperty -Parameter -WA:SilentlyContinue | ? {$rptCfgNames -icontains $_.Name -and $bypassCfg -inotcontains $_.Name} | Export-CliXml -Path "$Path\Reporting\ReportingCfg.xml"; PostExportItem; } if($Configuration -icontains "Scheduler") { PreExportItem -Name:"job templates" -Target:"$Path\Scheduler\HpcJobTemplate" -IsFolder:$true; Get-HpcJobTemplate -WV:+Global:WarningForCmdlet | % { Export-HpcJobTemplate -Template $_ -Path "$Path\Scheduler\HpcJobTemplate\$($_.Name).xml" -WV:+Global:WarningForCmdlet; } PostExportItem; PreExportItem -Name:"job template ACL" -Target:"$Path\Scheduler\HpcJobTemplate\HpcJobTemplateAcl.xml" -IsFolder:$false; Get-HpcJobTemplate | Get-HpcJobTemplateAcl -WV:+Global:WarningForCmdlet | Export-CliXml -Path "$Path\Scheduler\HpcJobTemplate\HpcJobTemplateAcl.xml"; PostExportItem; PreExportItem -Name:"scheduler environment variables" -Target:"$Path\Scheduler\SchedulerEnvVar.xml" -IsFolder:$false; ($envVars = Get-HpcClusterProperty -Environment) | ? { $bypassSchdEnvVar -inotcontains $_.Name } | Export-Clixml -Path "$Path\Scheduler\SchedulerEnvVar.xml"; WriteWarning "Environment variables CCP_CLUSTER_NAME, CCP_MPI_NETMASK, CCP_SERVICEREGISTRATION_PATH and WCF_NETWORKPREFIX are not exported because it's very likely they don't work with another cluster when being imported later."; PostExportItem; PreExportItem -Name:"scheduler configurations" -Target:"$Path\Scheduler\SchedulerCfg.xml" -IsFolder:$false; $schdCfg = Get-HpcClusterProperty -WV:+Global:WarningForCmdlet | ? { ($envVars|%{$_.Name}) -inotcontains $_.Name -and $diagCfgNames -inotcontains $_.Name -and $mgmtCfgNames -inotcontains $_.Name -and $rptCfgNames -inotcontains $_.Name -and $bypassCfg -inotcontains $_.Name}; $schdCfg | Export-Clixml -Path "$Path\Scheduler\SchedulerCfg.xml"; if($Configuration -icontains "Management") { $Global:WarningForCmdlet = $null; } PostExportItem; $schdCfg | % { if( $redirectToExportFolderCfg -icontains $_.Name -and !([string]::IsNullOrEmpty($_.Value)) ) { $fileName = [System.IO.Path]::GetFileName($_.Value); PreExportItem -Name:$_.Name -Target:"$Path\Scheduler\$($_.Name)\$fileName" -IsFolder:$false; if (!(Test-Path "$Path\Scheduler\$($_.Name)")) { New-Item -Path "$Path\Scheduler\$($_.Name)" -ItemType directory | out-null; } Copy-Item $_.Value "$Path\Scheduler\$($_.Name)\$fileName"; PostExportItem; WriteWarning "Only one assembly file is exported for $($_.Name) If it has dependencies on other assemblies, you need to export them manually."; } } } if($Configuration -icontains "SOA") { PreExportItem -Name:"SOA service registration files" -Target:"$Path\SOA\Registration" -IsFolder:$true; $svcRegFileSource = (Get-HpcClusterRegistry -PropertyName ServiceRegistrationShare).Value if( $svcRegFileSource.IndexOf(';') -ne -1) { WriteWarning "When the ServiceRegistrationShare cluster property value contains multiple paths seperated by ';', only the first path is exported."; $svcRegFileSource = $svcRegFileSource.SubString(0, $svcRegFileSource.IndexOf(';')); } Copy-Item "$svcRegFileSource\*" "$Path\SOA\Registration" -Recurse; WriteWarning "For SOA services, only registration files are exported. You need to export service assemblies manually."; PostExportItem; } WriteWarning ("Some configurations are not exported due to either security reason or it's not supported to import them later: "+ [string]::join(", ", $bypassCfg) + "."); WriteWarning "Some exported configurations may refer to the cluster name or UNC path. You need to review and change appropriately before importing them to another cluster later."; $Global:Xml += '</ExportedConfigurations>'; $Global:Xml | Out-File "$Path\MetaData.xml" -Encoding:utf8; WriteOutput "Exporting is completed. $Global:SuccessCount configurations are exported successfully. $Global:FailureCount configurations fail to be exported."; if ( $error ) { $error >> "$Path\ExportError.log"; } if ( $Global:Warning ) { $Global:Warning > "$Path\ExportWarning.log"; } $Global:Verbose > "$Path\ExportVerbose.log";