scripts/Firmware.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 Firmware module Cmdlets #> function Get-iBMCInbandFirmware { <# .SYNOPSIS Query information about the updatable inband firmware resource collection of a server. .DESCRIPTION Query information about the updatable firmware resources of a server. Include SPService and all inband firmwares. .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 PSObject[] Returns PSObject which contains all updatable firmware infomation 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:\> $Firmwares = Get-iBMCInbandFirmware $session PS C:\> $Firmwares | fl Host : 10.1.1.2 SR430C-M 1G (SAS3108)@[RAID Card1] : 4.270.00-4382 LOM (X722)@[LOM] : 3.33 0x80000f09 255.65535.255 SPService : @{APPVersion=1.09; OSVersion=1.09; DataVersion=1.09} .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCOutbandFirmware Update-iBMCInbandFirmware Update-iBMCOutbandFirmware Invoke-iBMCFileUpload Get-iBMCSPTaskResult Set-iBMCSPService 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 BMC updatable inband firmware function") $ScriptBlock = { param($RedfishSession) $Logger.info($(Trace-Session $RedfishSession "Invoke Get BMC updatable inband firmware now")) $Output = New-Object PSObject # in-band try { $Logger.info($(Trace-Session $RedfishSession "Invoke Get BMC updatable inband firmware now")) $Path = "/Managers/$($RedfishSession.Id)/SPService/DeviceInfo" $DeviceInfo = Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse for ($idx = 0; $idx -lt $BMC.InBandFirmwares.Count; $idx++) { $DeviceName = $BMC.InBandFirmwares[$idx]; $Devices = $DeviceInfo."$DeviceName"; if ($null -ne $Devices -and $Devices -is [Array] -and $Devices.Count -gt 0) { $Devices | ForEach-Object { $Name = $_.DeviceName $Model = $_.Controllers[0].Model $Position = $_.Position $Version = $_.Controllers[0].FirmwareVersion $Key = "$($Name) ($($Model))@[$($Position)]" $Output | Add-Member -MemberType NoteProperty $Key $Version } } } } catch { $Logger.warn($(Trace-Session $RedfishSession "Failed to load inband firmwares, reason: $_")) } # SP try { $Logger.info($(Trace-Session $RedfishSession "Invoke Get SPService version now")) $Path = "/Managers/$($RedfishSession.Id)/SPService" $SPService = Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse $Output | Add-Member -MemberType NoteProperty "SPService" $SPService.Version } catch { $Logger.warn($(Trace-Session $RedfishSession "Failed to get SPService, reason: $_")) throw $(Get-i18n FAIL_SP_NOT_SUPPORT) } return $(Update-SessionAddress $RedfishSession $Output) } 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 BMC updatable inband firmware task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession))) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } function Get-iBMCOutbandFirmware { <# .SYNOPSIS Query information about the updatable outband firmware resource collection of a server. .DESCRIPTION Query information about the updatable firmware resources of a server. Only those out-band firmwares is included: - ActiveBMC - BackupBMC - Bios - all CPLD, example: MainBoardCPLD, chassisDiskBP1CPLD .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 PSObject[] Returns PSObject which contains all updatable firmware infomation 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:\> $Firmwares = Get-iBMCOutbandFirmware $session PS C:\> $Firmwares | fl Host : 10.1.1.2 ActiveBMC : 3.18 BackupBMC : 3.18 Bios : 0.81 MainBoardCPLD : 2.02 chassisDiskBP1CPLD : 1.10 .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCInbandFirmware Update-iBMCInbandFirmware Update-iBMCOutbandFirmware Invoke-iBMCFileUpload Get-iBMCSPTaskResult Set-iBMCSPService 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 BMC updatable outband firmware function") $ScriptBlock = { param($RedfishSession) $Logger.info($(Trace-Session $RedfishSession "Invoke Get BMC updatable outband firmware now")) $Output = New-Object PSObject # out-band $Logger.info($(Trace-Session $RedfishSession "Invoke Get BMC updatable outband firmware now")) $Path = "/UpdateService/FirmwareInventory" $GetMembersResponse = Invoke-RedfishRequest $RedfishSession $Path | ConvertFrom-WebResponse $Members = $GetMembersResponse.Members for ($idx = 0; $idx -lt $Members.Count; $idx++) { $Member = $Members[$idx] $OdataId = $Member.'@odata.id' $InventoryName = $OdataId.Split("/")[-1] if ($InventoryName -in $BMC.OutBandFirmwares -or $InventoryName -like '*CPLD') { $Inventory = Invoke-RedfishRequest $RedfishSession $OdataId | ConvertFrom-WebResponse $Output | Add-Member -MemberType NoteProperty $Inventory.Name $Inventory.Version } } return $(Update-SessionAddress $RedfishSession $Output) } 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 BMC updatable outband firmware task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession))) } $Results = Get-AsyncTaskResults $tasks return ,$Results } finally { Close-Pool $pool } } end { } } function Update-iBMCInbandFirmware { <# .SYNOPSIS Updata iBMC Inband firmware. .DESCRIPTION Updata iBMC Inband firmware. This function transfers firmware to SP service. Those transfered firmwares takes effect upon next system restart when SP Service start is enabled (Set-iBMCSPService function is provided for this). Tips: Only V5 servers used with BIOS version later than 0.39 support this function. .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 Type Indicates the firmware type to be updated. Support value set: "Firmware", "SP". - Firmware: NIC, Raid - SP: Smart Provisioning Service .PARAMETER FileUri Indicates the file uri of firmware update image file. - When "Type" is Firmware: The firmware upgrade file is in .zip format. It supports HTTPS, SFTP, NFS, CIFS, SCP file transfer protocols. The URI cannot contain the following special characters: ||, ;, &&, $, |, >>, >, < For examples: - remote path: protocol://username:password@hostname/directory/Firmware.zip - When "Type" is SP: The firmware upgrade file is in .ISO format. support only the CIFS and NFS protocols. The URI cannot contain the following special characters: ||, ;, &&, $, |, >>, >, < For examples: - remote path: nfs://username:password@hostname/directory/Firmware.ISO .PARAMETER SignalFileUri Indicates the file path of the certificate file of the upgrade file. It is mandatory when upgrade Firmware while it is redundant when upgrade SP. - Signal file should be in .asc format - it supports HTTPS, SFTP, NFS, CIFS, SCP file transfer protocols. - The URI cannot contain the following special characters: ||, ;, &&, $, |, >>, >, < For examples: - remote path: protocol://username:password@hostname/directory/Firmware.zip.asc .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:\> Update-iBMCInbandFirmware -Session $session -Type Firmware ` -FileUri "nfs://10.10.10.2/data/nfs/NIC(X722)-Electrical-05022FTM-FW(3.33).zip" ` -SignalFileUri "nfs://10.10.10.2/data/nfs/NIC(X722)-Electrical-05022FTM-FW(3.33).zip.asc" ` -UpgradeMode Recover PS C:\> Set-iBMCSPService -Session $session -StartEnabled $true -SysRestartDelaySeconds 60 PS C:\> Set-iBMCServerPower -Session $session -ResetType ForceRestart This example shows how to update inband firmware with remote file, enabled SP service and restart server .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> Update-iBMCInbandFirmware -Session $session -Type SP ` -FileUri "nfs://10.10.10.2/data/nfs/Firmware.ISO" ` -UpgradeMode Recover This example shows how to update SP with remote file. .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCInbandFirmware Get-iBMCOutbandFirmware Update-iBMCOutbandFirmware Invoke-iBMCFileUpload Get-iBMCSPTaskResult Set-iBMCSPService Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session, [String[]] [ValidateSet("Firmware", "SP")] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] $Type, [String[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] $FileUri, [String[]] [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] $SignalFileUri, [UpgradeMode[]] [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] $UpgradeMode = [UpgradeMode]::Recover ) begin { } process { Assert-ArrayNotNull $Session 'Session' Assert-ArrayNotNull $Type 'Type' Assert-ArrayNotNull $FileUri 'FileUri' Assert-ArrayNotNull $UpgradeMode 'UpgradeMode' $FirmwareTypeList = Get-MatchedSizeArray $Session $Type 'Session' 'Type' $FileUriList = Get-MatchedSizeArray $Session $FileUri 'Session' 'FileUri' $UpgradeModeList = Get-MatchedSizeArray $Session $UpgradeMode 'Session' 'UpgradeMode' $SignalFileUriList = Get-OptionalMatchedSizeArray $Session $SignalFileUri $Logger.info("Invoke upgrade BMC inband firmware function") $ScriptBlock = { param($RedfishSession, $InbandFirmwareType, $ImageFilePath, $SignalFilePath, $UpgradeMode) $Logger.info($(Trace-Session $RedfishSession "Invoke upgrade $InbandFirmwareType now")) # transfer firmware image file $GetSPUpdateService = "/Managers/$($RedfishSession.Id)/SPService/SPFWUpdate" $SPServices = Invoke-RedfishRequest $RedfishSession $GetSPUpdateService | ConvertFrom-WebResponse if ($SPServices.Members.Count -gt 0) { $Payload = @{ "Parameter" = "all"; "UpgradeMode" = $UpgradeMode; "ActiveMethod" = "OSRestart"; } | Resolve-EnumValues if ($InbandFirmwareType -eq "Firmware") { $ImageURI = Invoke-FileUploadIfNeccessary $RedfishSession $ImageFilePath $BMC.InBandImageFileSupportSchema $SignalURI = Invoke-FileUploadIfNeccessary $RedfishSession $SignalFilePath $BMC.SignalFileSupportSchema $Payload.ImageURI = $ImageURI $Payload.SignalURI = $SignalURI $Payload.ImageType = "Firmware" } else { $ImageURI = Invoke-FileUploadIfNeccessary $RedfishSession $ImageFilePath $BMC.SPImageFileSupportSchema if ($null -ne $SignalURI) { $Payload.SignalURI = Invoke-FileUploadIfNeccessary $RedfishSession $SignalFilePath $BMC.SignalFileSupportSchema } else { $Payload.SignalURI = "" } $Payload.ImageURI = $ImageURI $Payload.ImageType = "SP" } if ($Payload.ImageURI.StartsWith('/tmp', "CurrentCultureIgnoreCase")) { $Payload.ImageURI = "file://$($Payload.ImageURI)" } if ($Payload.SignalURI.StartsWith('/tmp', "CurrentCultureIgnoreCase")) { $Payload.SignalURI = "file://$($Payload.SignalURI)" } $LogPayload = $Payload.Clone() $LogPayload.ImageURI = Protect-NetworkUriUserInfo $LogPayload.ImageURI $LogPayload.SignalURI = Protect-NetworkUriUserInfo $LogPayload.SignalURI $Logger.Info($(Trace-Session $RedfishSession "Sending payload: $($LogPayload | ConvertTo-Json)")) $SPServiceOdataId = $SPServices.Members[0].'@odata.id' $SPFWUpdateUri = "$SPServiceOdataId/Actions/SPFWUpdate.SimpleUpdate" Invoke-RedfishRequest $RedfishSession $SPFWUpdateUri 'POST' $Payload | Out-Null Start-Sleep -Seconds 3 $Uri = New-Object System.Uri($Payload.ImageURI) $FileName = $Uri.Segments[-1] # $TransferStart = $false $WaitTransfer = 200 while ($WaitTransfer -gt 0) { # wait transfer progress finished $Transfer = Invoke-RedfishRequest $RedfishSession $SPServiceOdataId | ConvertFrom-WebResponse $Percent = $Transfer.TransferProgressPercent $Logger.Info($(Trace-Session $RedfishSession "File $($Transfer.TransferFileName) transfer $($Percent)%")) if ($Transfer.TransferFileName -eq $FileName) { if ($null -ne $Percent -and $Percent -ge 0) { $Logger.Info($(Trace-Session $RedfishSession "File $FileName transfer start.")) # $TransferStart = $true break } } $WaitTransfer = $WaitTransfer - 1 Start-Sleep -Milliseconds 100 } # if (-not $TransferStart) { # throw $(Get-i18n "FAIL_SP_FILE_TRANSFER") # } return $Transfer # Enable SP Service # $SPServicePath = "/Managers/$($RedfishSession.Id)/SPService" # $EnableSpServicePayload = @{ # "SPStartEnabled"= $true; # "SysRestartDelaySeconds"= 30; # "SPTimeout"= 7200; # "SPFinished"= $true; # } # Invoke-RedfishRequest $RedfishSession $SPServicePath 'PATCH' $EnableSpServicePayload | Out-Null # try { # # Restart Server # if ($Transfered) { # $Payload = @{ # "ResetType" = [ResetType]::ForceRestart; # } | Resolve-EnumValues # $Path = "/Systems/$($RedfishSession.Id)/Actions/ComputerSystem.Reset" # Invoke-RedfishRequest $RedfishSession $Path 'POST' $Payload | Out-Null # } # } catch { # throw $(Get-i18n "FAIL_SP_RESET_SYSTEM") # } # return $null } else { throw $(Get-i18n "FAIL_SP_NOT_SUPPORT") } } try { $ScriptBlockParameters = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $FirmwareType = $FirmwareTypeList[$idx]; $ImageFilePath = $FileUriList[$idx] $SignalFilePath = $SignalFileUriList[$idx] $UpgradeMode_ = $UpgradeModeList[$idx] if ($FirmwareType -eq "Firmware" -and $null -eq $SignalFilePath) { throw $(Get-i18n "FAIL_SIGNAL_URI_REQUIRED") } $Parameters = @($RedfishSession, $FirmwareType, $ImageFilePath, $SignalFilePath, $UpgradeMode_) [Void] $ScriptBlockParameters.Add($Parameters) } $tasks = New-Object System.Collections.ArrayList for ($idx = 0; $idx -lt $Session.Count; $idx++) { $Logger.info($(Trace-Session $RedfishSession "Submit upgrade BMC inband firmware task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $ScriptBlockParameters[$idx])) } $TransferResults = Get-AsyncTaskResults $tasks return $(Wait-SPFileTransfer $pool $Session $TransferResults -ShowProgress) } finally { Close-Pool $pool } } end { } } function Set-iBMCSPService { <# .SYNOPSIS Modify properties of the SP service resource. .DESCRIPTION Modify properties of the SP(Smart Provisioning) service resource. Tips: only V5 servers used with BIOS version later than 0.39 support this function. .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 StartEnabled Indicates Whether SP start is enabled. Support values are powershell boolean value: $true(1), $false(0). .PARAMETER SysRestartDelaySeconds Indicates Maximum time allowed for the restart of the OS. A positive integer value is accept. .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-iBMCSPService -Session $session -StartEnabled $true -SysRestartDelaySeconds 60 .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCInbandFirmware Get-iBMCOutbandFirmware Update-iBMCInbandFirmware Update-iBMCOutbandFirmware Invoke-iBMCFileUpload Get-iBMCSPTaskResult Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session, [Boolean[]] [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 1)] $StartEnabled, [int[]] [ValidateRange(1, [int]::MaxValue)] [parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 2)] $SysRestartDelaySeconds ) begin { } process { Assert-ArrayNotNull $Session 'Session' $StartEnabledList = Get-OptionalMatchedSizeArray $Session $StartEnabled $SysRestartDelaySecondsList = Get-OptionalMatchedSizeArray $Session $SysRestartDelaySeconds $Logger.info("Invoke set SP Service function") $ScriptBlock = { param($RedfishSession, $Enabled, $SysRestartDelaySeconds) $Logger.info($(Trace-Session $RedfishSession "Invoke set SP Service function now")) # Enable SP Service $SPServicePath = "/Managers/$($RedfishSession.Id)/SPService" $EnableSpServicePayload = @{ "SPStartEnabled"= $Enabled; "SysRestartDelaySeconds"= $SysRestartDelaySeconds; "SPTimeout"= 7200; "SPFinished"= $false; } | Remove-EmptyValues $Logger.Info($(Trace-Session $RedfishSession "Sending payload: $($EnableSpServicePayload | ConvertTo-Json)")) Invoke-RedfishRequest $RedfishSession $SPServicePath 'PATCH' $EnableSpServicePayload | Out-Null return $null } try { $tasks = New-Object System.Collections.ArrayList $ParametersList = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $Parameters = @($RedfishSession, $StartEnabledList[$idx], $SysRestartDelaySecondsList[$idx]) if ($null -eq $StartEnabledList[$idx] -and $null -eq $SysRestartDelaySecondsList[$idx]) { throw $(Get-i18n FAIL_NO_UPDATE_PARAMETER) } [Void] $ParametersList.Add($Parameters) } for ($idx = 0; $idx -lt $ParametersList.Count; $idx++) { $Logger.info($(Trace-Session $RedfishSession "Submit set SP Service task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $ParametersList[$idx])) } return Get-AsyncTaskResults $tasks } finally { Close-Pool $pool } } end { } } function Get-iBMCSPTaskResult { <# .SYNOPSIS Query information about the configuration result resource of the SP service. .DESCRIPTION Query information about the configuration result resource of the SP service. Tips: only V5 servers used with BIOS version later than 0.39 support this function. .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 PSObject[] Returns PSObject indicates configuration result resource of SP Service 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:\> $Result = Get-iBMCSPTaskResult -Session $session PS C:\> $Result Host : 10.1.1.2 Id : 1 Name : SP Result Status : Idle OSInstall : Clone : Recover : .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCInbandFirmware Get-iBMCOutbandFirmware Update-iBMCInbandFirmware Update-iBMCOutbandFirmware Invoke-iBMCFileUpload Set-iBMCSPService 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 SP Result function") $ScriptBlock = { param($RedfishSession) $Logger.info($(Trace-Session $RedfishSession "Invoke Get SP Result function now")) $SPResultMemberPath = "/Managers/$($RedfishSession.Id)/SPService/SPResult" $Collection = Invoke-RedfishRequest $RedfishSession $SPResultMemberPath | ConvertFrom-WebResponse $Members = $Collection.Members if ($Members.Count -ge 1) { $GetSPResultPath = $Members[0].'@odata.id' $Result = Invoke-RedfishRequest $RedfishSession $GetSPResultPath | ConvertFrom-WebResponse $CleanUp = $Result | Clear-OdataProperties return $(Update-SessionAddress $RedfishSession $CleanUp) } else { 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] $Logger.info($(Trace-Session $RedfishSession "Submit Get SP Result task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock @($RedfishSession))) } return Get-AsyncTaskResults $tasks } finally { Close-Pool $pool } } end { } } function Update-iBMCOutbandFirmware { <# .SYNOPSIS Updata iBMC Outband firmware. .DESCRIPTION Updata iBMC Outband firmware. .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 FileUri Indicates the file uri of firmware update image file. File Uri should be a string of up to 256 characters. It supports HTTPS, SCP, SFTP, CIFS, TFTP, NFS and FILE file transfer protocols. For examples: - local path: C:\2288H_V5_5288_V5-iBMC-V318.hpm or \\192.168.1.2\2288H_V5_5288_V5-iBMC-V318.hpm - ibmc local temporary path: /tmp/2288H_V5_5288_V5-iBMC-V318.hpm - remote path: protocol://username:password@hostname/directory/2288H_V5_5288_V5-iBMC-V318.hpm .OUTPUTS PSObject[] Returns the update firmware task details 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:\> Update-iBMCOutbandFirmware -Session $session -FileUri E:\2288H_V5_5288_V5-iBMC-V318.hpm Host : 10.1.1.2 Id : 1 Name : Upgarde Task ActivityName : [10.1.1.2] Upgarde Task TaskState : Completed StartTime : 2018-11-23T08:57:45+08:00 EndTime : 2018-11-23T09:01:24+08:00 TaskStatus : OK TaskPercent : 100% This example shows how to update outband firmware with local file .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> Update-iBMCOutbandFirmware -Session $session -FileUri '/tmp/2288H_V5_5288_V5-iBMC-V318.hpm' Host : 10.1.1.2 Id : 1 Name : Upgarde Task ActivityName : [10.1.1.2] Upgarde Task TaskState : Completed StartTime : 2018-11-23T08:57:45+08:00 EndTime : 2018-11-23T09:01:24+08:00 TaskStatus : OK TaskPercent : 100% This example shows how to update outband firmware with ibmc temp file .EXAMPLE PS C:\> $credential = Get-Credential PS C:\> $session = Connect-iBMC -Address 10.1.1.2 -Credential $credential -TrustCert PS C:\> Update-iBMCOutbandFirmware -Session $session ` -FileUri nfs://10.10.10.2/data/nfs/2288H_V5_5288_V5-iBMC-V318.hpm Host : 10.1.1.2 Id : 1 Name : Upgarde Task ActivityName : [10.1.1.2] Upgarde Task TaskState : Completed StartTime : 2018-11-23T08:57:45+08:00 EndTime : 2018-11-23T09:01:24+08:00 TaskStatus : OK TaskPercent : 100% This example shows how to update outband firmware with NFS network file .LINK https://github.com/Huawei/Huawei-iBMC-Cmdlets Get-iBMCInbandFirmware Get-iBMCOutbandFirmware Update-iBMCInbandFirmware Invoke-iBMCFileUpload Get-iBMCSPTaskResult Set-iBMCSPService Connect-iBMC Disconnect-iBMC #> [CmdletBinding()] param ( [RedfishSession[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Session, [String[]] [parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 2)] $FileUri ) begin { } process { Assert-ArrayNotNull $Session 'Session' Assert-ArrayNotNull $FileUri 'FileUri' $FileUriList = Get-MatchedSizeArray $Session $FileUri 'Session' 'FileUri' $Logger.info("Invoke upgrade BMC outband firmware function") $ScriptBlock = { param($RedfishSession, $ImageFilePath) $Logger.info($(Trace-Session $RedfishSession "Invoke upgrade outband firmware now")) $ImageFilePath = Invoke-FileUploadIfNeccessary $RedfishSession $ImageFilePath $BMC.OutBandImageFileSupportSchema $Payload = @{'ImageURI' = $ImageFilePath; } if (-not $ImageFilePath.StartsWith('/tmp', "CurrentCultureIgnoreCase")) { $ImageFileUri = New-Object System.Uri($ImageFilePath) if ($ImageFileUri.Scheme -ne 'file') { $Payload."TransferProtocol" = $ImageFileUri.Scheme.ToUpper(); } } $Clone = $Payload.clone() $Clone.ImageURI = Protect-NetworkUriUserInfo $ImageFilePath $Logger.info($(Trace-Session $RedfishSession "Sending payload: $($Clone | ConvertTo-Json)")) # try submit upgrade outband firmware task $Path = "/UpdateService/Actions/UpdateService.SimpleUpdate" $Response = Invoke-RedfishRequest $RedfishSession $Path 'Post' $Payload return $Response | ConvertFrom-WebResponse } try { $tasks = New-Object System.Collections.ArrayList $pool = New-RunspacePool $Session.Count for ($idx = 0; $idx -lt $Session.Count; $idx++) { $RedfishSession = $Session[$idx] $ImageFilePath = $FileUriList[$idx] $Parameters = @($RedfishSession, $ImageFilePath) $Logger.info($(Trace-Session $RedfishSession "Submit upgrade BMC outband firmware task")) [Void] $tasks.Add($(Start-ScriptBlockThread $pool $ScriptBlock $Parameters)) } $RedfishTasks = Get-AsyncTaskResults $tasks $Logger.Info("Upgrade outband firmware tasks: " + $RedfishTasks) return Wait-RedfishTasks $pool $Session $RedfishTasks -ShowProgress } finally { Close-Pool $pool } } end { } } |