scripts/Boot.ps1
# Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved. # This program is free software; you can redistribute it and/or modify # it under the terms of the MIT License # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # MIT License for more detail <# NOTE: iBMC boot module Cmdlets #> function Get-iBMCBootupSequence { <# .SYNOPSIS Query bios boot up device sequence. .DESCRIPTION Query bios boot up device sequence. Boot up device contains: Hdd, Cd, Pxe, Others. .PARAMETER Session iBMC redfish session object which is created by Connect-iBMC cmdlet. A session object identifies an iBMC server to which this cmdlet will be executed. .OUTPUTS Array[String[]] Returns string array identifies boot up device in order if cmdlet executes successfully. In case of an error or warning, exception will be returned. .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> $Sequence = Get-iBMCBootupSequence $session PS C:\> $Sequence Host BootupSequence ---- -------------- 10.1.1.2 {Pxe, HDD, Cd, Others} PS C:\> $Sequence | fl Host : 10.1.1.2 BootupSequence : {Pxe, HDD, Cd, Others} .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Set-iBMCBootupSequence Get-iBMCBootSourceOverride Set-iBMCBootSourceOverride Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session ) begin { } process { Assert-ArrayNotNull $Session 'Session' $Logger.info("Invoke Get Bootup Sequence function") $ScriptBlock = { param($RedfishSession) $Path = "/redfish/v1/Systems/$($RedfishSession.Id)" $Response = $(Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse) # V3 if ($null -ne $Response.Oem.Huawei.BootupSequence) { $Logger.info($(Trace-Session $RedfishSession "Find System.Oem.Huawei.BootupSequence, return directly")) $Clone = New-Object PSObject $Clone | Add-Member -MemberType NoteProperty "BootupSequence" $Response.Oem.Huawei.BootupSequence return $(Update-SessionAddress $RedfishSession $Clone) } else { # V5 $Logger.info($(Trace-Session $RedfishSession "V5 BMC, will try get sequence from BIOS API")) $BiosPath = "$Path/Bios" $BiosResponse = $(Invoke-RedfishRequest $RedfishSession $BiosPath | ConvertFrom-WebResponse) $Attrs = $BiosResponse.Attributes $seq = New-Object System.Collections.ArrayList 0..3 | ForEach-Object { $BootType = $Attrs."BootTypeOrder$_" [Void] $seq.Add($BMC.V52V3Mapping[$BootType]) } $Clone = New-Object PSObject $Clone | Add-Member -MemberType NoteProperty "BootupSequence" $seq.ToArray() return $(Update-SessionAddress $RedfishSession $Clone) } } try { $tasks = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $Logger.info($(Trace-Session $RedfishSession "Submit Get Bootup Sequence task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession))) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } function Set-iBMCBootupSequence { <# .SYNOPSIS Set bios boot up device sequence. .DESCRIPTION Set bios boot up device sequence. Boot up device contains: Hdd, Cd, Pxe, Others. New boot up sequence settings take effect upon the next restart of the system. .PARAMETER Session iBMC redfish session object which is created by Connect-iBMC cmdlet. A session object identifies an iBMC server to which this cmdlet will be executed. .PARAMETER BootSequence A array set of boot device in order, should contains all available boot devices. example: ,@('Hdd', 'Cd', 'Pxe', 'Others') .OUTPUTS None Returns None if cmdlet executes successfully. In case of an error or warning, exception will be returned. .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> $BootUpSequence = ,@('Pxe', 'Hdd', 'Cd', 'Others') PS C:\> Set-iBMCBootupSequence $session $BootUpSequence Set boot up device sequence for single iBMC server .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2,10.1.1.3 -Credential $credential -TrustCert PS C:\> $BootUpSequence = @(@('Pxe', 'Hdd', 'Cd', 'Others'), @('Cd', 'Pxe', 'Hdd', 'Others')) PS C:\> Set-iBMCBootupSequence $session $BootUpSequence Set boot up device sequence for multiple iBMC server .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCBootupSequence Get-iBMCBootSourceOverride Set-iBMCBootSourceOverride Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session, [BootSequence[][]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1)] $BootSequence ) begin { } process { Assert-ArrayNotNull $Session 'Session' Assert-ArrayNotNull $BootSequence 'BootSequence' $BootSequenceList = Get-MatchedSizeArray $Session $BootSequence 'Session' 'BootSequence' # validate boot sequence input $BootSequenceList | ForEach-Object { if ($null -ne $_ -or $_.Count -eq 4) { $ValidSet = Get-EnumNames "BootSequence" $diff = Compare-Object $_ $ValidSet -PassThru if ($null -eq $diff) { return } } throw [String]::format($(Get-i18n "ERROR_ILLEGAL_BOOT_SEQ"), $_ -join ",") } $Logger.info("Invoke Set Bootup Sequence function") $ScriptBlock = { param($RedfishSession, $BootSequence) $Path = "/redfish/v1/Systems/$($RedfishSession.Id)" $Response = Invoke-RedfishRequest $RedfishSession $Path $System = $Response | ConvertFrom-WebResponse if ($null -ne $System.Oem.Huawei.BootupSequence) { # V3 $Logger.info($(Trace-Session $RedfishSession "[V3] Will set boot sequence using System resource")) $Payload = @{ "Oem" = @{ "Huawei" = @{ "BootupSequence" = $BootSequence; } | Resolve-EnumValues; }; } $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($Payload | ConvertTo-Json -Depth 5)")) $Headers = @{'If-Match' = $Response.Headers.get('ETag'); } Invoke-RedfishRequest $RedfishSession $Path 'PATCH' $Payload $Headers | Out-Null return $null } else { # V5 $Logger.info($(Trace-Session $RedfishSession "[V5] Will set boot sequence using BIOS settings resource")) $SetBiosPath = "$Path/Bios/Settings" $V5BootSequence = @{} for ($idx = 0; $idx -lt $BootSequence.Count; $idx++) { $BootType = $BMC.V32V5Mapping[$BootSequence[$idx].toString()] $V5BootSequence."BootTypeOrder$idx" = $BootType } $Logger.info($(Trace-Session $RedfishSession "[V5] Boot device sequence: $V5BootSequence")) $Payload = @{"Attributes" = $V5BootSequence; } $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($Payload | ConvertTo-Json -Depth 5)")) Invoke-RedfishRequest $RedfishSession $SetBiosPath 'PATCH' $Payload | Out-Null return $null } } try { $tasks = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $Parameters = @($RedfishSession, $BootSequenceList[$idx]) $Logger.info($(Trace-Session $RedfishSession "Submit Get Bootup Sequence task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $Parameters)) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } function Get-iBMCBootSourceOverride { <# .SYNOPSIS Query bios boot source override target. .DESCRIPTION Query bios boot source override target. Boot up device contains: 'None', 'Pxe', 'Floppy', 'Cd', 'Hdd', 'BiosSetup'. .PARAMETER Session iBMC redfish session object which is created by Connect-iBMC cmdlet. A session object identifies an iBMC server to which this cmdlet will be executed. .OUTPUTS String[] Returns bios boot source override target if cmdlet executes successfully. In case of an error or warning, exception will be returned. .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> $BootSourceOverride = Get-iBMCBootSourceOverride $session PS C:\> $BootSourceOverride Host BootSourceOverrideTarget BootSourceOverrideEnabled ---- ------------------------ ------------------------- 10.1.1.2 None Disabled PS C:\> $BootSourceOverride | fl Host : 10.1.1.2 BootSourceOverrideTarget : None BootSourceOverrideEnabled : Disabled .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCBootupSequence Set-iBMCBootupSequence Set-iBMCBootSourceOverride Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session ) begin { } process { Assert-ArrayNotNull $Session 'Session' $Logger.info("Invoke Get Boot Source Override function") $ScriptBlock = { param($RedfishSession) $(Get-Logger).info($(Trace-Session $RedfishSession "Get boot source override target now")) $Path = "/redfish/v1/Systems/$($RedfishSession.Id)" $Response = $(Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse) $Properties = @( "BootSourceOverrideTarget", "BootSourceOverrideEnabled" ) $BootSourceOverride = Copy-ObjectProperties $Response.Boot $Properties return $(Update-SessionAddress $RedfishSession $BootSourceOverride) } try { $tasks = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $Logger.info($(Trace-Session $RedfishSession "Submit Get Boot Source Override task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession))) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } function Set-iBMCBootSourceOverride { <# .SYNOPSIS Modify bios boot source override target. .DESCRIPTION Modify bios boot source override target. Available boot source override target: 'None', 'Pxe', 'Floppy', 'Cd', 'Hdd', 'BiosSetup'. This boot source override target takes effect upon the next restart of the system. .PARAMETER Session iBMC redfish session object which is created by Connect-iBMC cmdlet. A session object identifies an iBMC server to which this cmdlet will be executed. .PARAMETER BootSourceOverrideTarget BootSourceOverrideTarget specifies the bios boot source override target .OUTPUTS Null Returns Null if cmdlet executes successfully. In case of an error or warning, exception will be returned. .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> Set-iBMCBootSourceOverride $session 'Pxe' 'Once' Set boot source override target for single iBMC server .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2,10.1.1.5 -Credential $credential -TrustCert PS C:\> Set-iBMCBootSourceOverride -Session $session -BootSourceOverrideTarget Pxe ` -BootSourceOverrideEnabled Once Set boot source override target for multiple iBMC server .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCBootupSequence Set-iBMCBootupSequence Get-iBMCBootSourceOverride Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session, [BootSourceOverrideTarget[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1)] $BootSourceOverrideTarget, [BootSourceOverrideEnabled[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 2)] $BootSourceOverrideEnabled ) begin { } process { Assert-ArrayNotNull $Session 'Session' Assert-ArrayNotNull $BootSourceOverrideTarget 'BootSourceOverrideTarget' $BootSourceOverrideTargetList = Get-MatchedSizeArray $Session $BootSourceOverrideTarget 'Session' 'BootSourceOverrideTarget' $BootSourceOverrideEnabledList = Get-MatchedSizeArray $Session $BootSourceOverrideEnabled 'Session' 'BootSourceOverrideEnabled' $Logger.info("Invoke Set Bootup Sequence function") $ScriptBlock = { param($RedfishSession, $BootSourceOverrideTarget, $BootSourceOverrideEnabled) $(Get-Logger).info($(Trace-Session $RedfishSession "Set boot source override target: $BootSourceOverrideTarget, $BootSourceOverrideEnabled")) $Path = "/redfish/v1/Systems/$($RedfishSession.Id)" $Payload = @{ "Boot" = @{ "BootSourceOverrideTarget" = $BootSourceOverrideTarget.toString(); "BootSourceOverrideEnabled" = $BootSourceOverrideEnabled.toString(); }; } $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($Payload | ConvertTo-Json)")) Invoke-RedfishRequest $RedfishSession $Path 'PATCH' $Payload | Out-Null return $null } try { $tasks = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $Parameters = @($RedfishSession, $BootSourceOverrideTargetList[$idx], $BootSourceOverrideEnabledList[$idx]) $Logger.info($(Trace-Session $RedfishSession "Submit Set Boot source override target task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $Parameters)) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } |