Struggeling with Invoke-WebRequest

lupinlicious 126 Reputation points
2023-01-31T11:52:43.47+00:00

Hello,

I'm trying to parse and download BIOS updates from Dell, when I run the script on a Dell OptiPlex 7080 I get the following error. Message: Cannot convert 'System.Object[]' to the type 'System.Uri' required by parameter 'Uri'. Specified method is not supported.

Invoke-WebRequest -Uri'https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab' -OutFile $CabPath -Verbose
		[int32]$n=1
		While(!(Test-Path $CabPath) -and $n -lt '3'){
Invoke-WebRequest -Uri'https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab' -OutFile $CabPath -Verbose
			$n++
		}

Any help would be appreciated!

Best regards

Microsoft Deployment Toolkit
Microsoft Deployment Toolkit
A collection of Microsoft tools and documentation for automating desktop and server deployment. Previously known as Microsoft Solution Accelerator for Business Desktop Deployment (BDD).
799 questions
PowerShell
PowerShell
A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
1,867 questions
{count} votes

6 answers

Sort by: Most helpful
  1. MotoX80 30,916 Reputation points
    2023-01-31T13:29:17.5933333+00:00

    You need a space between -Uri and the web address. You don't show what is in $cabpath and you are comparing an integer ($n) to a string ('3').

    Do it like this.

    $CabPath = 'c:\temp\dell.cab' 
    Invoke-WebRequest -Uri 'https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab' -OutFile $CabPath -Verbose
    
    $n = 1               # count retries
    While($true){                          
        if (Test-Path $CabPath) {
            "The file successfully downloaded."
            "Do something here."
            break
        } else {
            "Sleeping"
            start-sleep -Seconds 120       # if it didn't work the first time, wait for a while to see if the problem goes away.    
            Invoke-WebRequest -Uri 'https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab' -OutFile $CabPath -Verbose
    	    $n++
        }
        if ($n -gt 3) {             # How many times do you want to retry? 
            "Download failed. Retry limit reached. Aborting download." 
            "Do something else here because you cannot continue since the file did not download."
            break
        } 
    }
    

  2. lupinlicious 126 Reputation points
    2023-01-31T15:44:13.2833333+00:00

    ignore this comment


  3. lupinlicious 126 Reputation points
    2023-02-01T18:53:57.37+00:00

    Thanks, guys! I have tested the script on three laptops and it seems fine, BIOS is getting downloaded and installed.
    However, I'm struggling with a stationary computer and I suspect these lines to be problematic.

    $TargetLink = $Target.InstallableItem.OriginFile.OriginUri
    $TargetFileName = $Target.InstallableItem.OriginFile.FileName
    Invoke-WebRequest -Uri $TargetLink -OutFile "$scriptDirectory\Files\$ComputerModel\$TargetFileName" -UseBasicParsing -Verbose
    

    The error message that keeps popups up would be "Cannot convert 'System.Object[]' to the type 'System.Uri' required by parameter 'Uri'. Specified method is not supported." It complains specifically over would be Invoke-WebRequest...

    The whole code:

            $ComputerModel = Get-WmiObject -Class Win32_computersystem | Select-Object -ExpandProperty Model
    		
    		# Test if Path exsist, otherwise create it
    		$path = "$ScriptDirectory\Files\$Computermodel"
    		If(!(test-path -PathType container $path))
    		{
    			  New-Item -ItemType Directory -Path $path
    		}
    
    		# <FORMAT CAB DOWNLOAD PATH>
    		$CabPath = "$ScriptDirectory\Files\$Computermodel\dellsdpcatalogpc.cab"
    		$destination = "$ScriptDirectory\Files\$Computermodel"
    
    		# Download Dell Cab File
    		Invoke-WebRequest -Uri "https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab" -OutFile $CabPath -UseBasicParsing -Verbose
    		[int32]$n=1
    		While(!(Test-Path $CabPath) -and $n -lt '3'){
    			Invoke-WebRequest -Uri "https://downloads.dell.com/Catalog/DellSDPCatalogPC.cab" -OutFile $CabPath -UseBasicParsing -Verbose
    			$n++
    		}
    
    		# <EXTRACT XML FROM CAB FILE>
    		If(Test-Path "$ScriptDirectory\Files\$Computermodel\DellSDPCatalogPC.xml"){Remove-Item -Path "$ScriptDirectory\Files\$Computermodel\DellSDPCatalogPC.xml" -Force -Verbose}
    
    		Expand $CabPath "$ScriptDirectory\Files\$Computermodel" -f:* 
    
    		# <IMPORT AND CREATE XML OBJECT>
    		If(Test-Path "$ScriptDirectory\Files\$Computermodel\DellSDPCatalogPC.xml"){[xml]$XML = Get-Content -Path "$ScriptDirectory\Files\$Computermodel\DellSDPCatalogPC.xml" -Verbose}
    		else{exit 15}
    
    		# <CREATE ARRAY OF DOWNLOADS>
    		$Downloads = $xml.SystemsManagementCatalog.SoftwareDistributionPackage
    
    		# <FIND TARGET DOWNLOAD FOR SPECIFIC DESIRED FUNCTION EXAMPLE>
    		$Model = ((Get-WmiObject win32_computersystem).Model).TrimEnd()
    		If (((($Model -match '7290') -or ($Model -match '7390') -or ($Model -match '7490')) -and (!($Model.EndsWith("AIO")) -or !($Model.EndsWith("M"))))){
    			$Target = $Downloads | Where-Object -FilterScript {
    			$PSitem.LocalizedProperties.Title -match '7290/7390/7490' -and $PSitem.LocalizedProperties.Title -notmatch $model + " AIO" -and $PSitem.LocalizedProperties.Title -notmatch $model + "M"
    			}
    		}
    		ElseIf (((($Model -match '7280') -or ($Model -match '7380') -or ($Model -match '7480')) -and (!($Model.EndsWith("AIO")) -or !($Model.EndsWith("M"))))){
    			$Target = $Downloads | Where-Object -FilterScript {
    			$PSitem.LocalizedProperties.Title -match '7280/7380/7480' -and $PSitem.LocalizedProperties.Title -notmatch $model + " AIO" -and $PSitem.LocalizedProperties.Title -notmatch $model + "M"
    			}
    		}
    		ElseIf (($Model.Contains("7080")) -and ((!($Model.EndsWith("AIO")) -or !($Model.EndsWith("M"))))){
    			$Target = $Downloads | Where-Object -FilterScript {
    			$PSitem.LocalizedProperties.Title -match "7080" -and $PSitem.LocalizedProperties.Title -notmatch $model + " AIO" -and $PSitem.LocalizedProperties.Title -notmatch $model + "M"
    			}
    		}		
    		Else{$Target = $Downloads | Where-Object -FilterScript {$PSitem.LocalizedProperties.Title -match $model -and $PSitem.Properties.PublicationState -match "Published"}}
    		$TargetLink = $Target.InstallableItem.OriginFile.OriginUri
    		$TargetFileName = $Target.InstallableItem.OriginFile.FileName
    		Invoke-WebRequest -Uri $TargetLink -OutFile "$scriptDirectory\Files\$ComputerModel\$TargetFileName" -UseBasicParsing -Verbose
    		$File = "$scriptDirectory\Files\$ComputerModel\$TargetFileName"
    
    
    
    		
    # <SET COMMAND ARGUMENTS FOR BIOS UPDATE>
    $cmds = "/s"
    
    # <UPDATE BIOS>
    execute-process -Path "$scriptDirectory\Files\$ComputerModel\$TargetFileName" $cmds -PassThru -wait
    
    

    Thaaaanks!

    0 comments No comments

  4. Rich Matheisen 44,006 Reputation points
    2023-02-01T19:39:13.99+00:00

    I expect that there were multiple matches in XML file placed into the $Target variable in this bit of code:

    	Else{
            $Target = $Downloads | 
                Where-Object -FilterScript {
                    $PSitem.LocalizedProperties.Title -match $model -and 
                    $PSitem.Properties.PublicationState -match "Published"}
        }
    
    

    If so, that would make $TargetLink an array, not a scalar. In that context the error you receive makes sense.


  5. MotoX80 30,916 Reputation points
    2023-02-01T22:00:12.13+00:00

    Personally, I prefer to have "chatty" scripts that display the contents of key variables so that I don't have to guess what input a given PS cmdlet is trying to process.

    Like this.

            $ComputerModel = Get-WmiObject -Class Win32_computersystem | Select-Object -ExpandProperty Model
    		"Computer model: {0}" -f $ComputerModel
    
            .....
    
    		# <FORMAT CAB DOWNLOAD PATH>
    		$CabPath = "$ScriptDirectory\Files\$Computermodel\dellsdpcatalogpc.cab"
    		$destination = "$ScriptDirectory\Files\$Computermodel"
            "Cab Path: {0}" -f $CabPath
            "Destination: {0}" -f $destination
    
            ......
    
    
    		$TargetLink = $Target.InstallableItem.OriginFile.OriginUri
    		$TargetFileName = $Target.InstallableItem.OriginFile.FileName
    		"TargetLink: {0}" -f $TargetLink
    		"TargetFileName: {0}" -f $TargetFileName
    		
            .....
    

    The problem with this technique is that if your variable is an array as Rich suggested, it might only display the first entry. So you would need to display the contents like this.

    		"TargetLink......"
            $TargetLink
    		"TargetFileName...."
            $TargetFileName 
    
    

    Or pipe the variable to format-list or format-table.

    0 comments No comments