Add Firefox-related functions, and improve web downloader

- Add Get-SanitizedFilename
- Add Get-RootedPath
- Modify Get-WebUrl to use these functions for more robustness
- Add Install-Firefox, which downloads and installs
- Add Set-FirefoxOptions, mostly stub for now, can set default browser
jowjDev
Micah R Ledbetter 8 years ago
parent 280b40c8fb
commit 6ac12c69d7

@ -53,6 +53,63 @@ $script:ScriptPath = $MyInvocation.MyCommand.Path
### Private support functions I use behind the scenes
<#
.description
Do some very basic filename sanitization
#>
function Get-SanitizedFilename {
[cmdletbinding()] param(
[Parameter(Mandatory=$true)] [String] $fileName
)
$invalidChars = [System.IO.Path]::GetInvalidFileNameChars()
$replacementCharacter = "_"
$newName = [System.String]::Copy($fileName)
foreach ($invChar in $invalidChars) {
$newName = $newName.Replace($invChar, $replacementCharacter)
}
return $newName
}
<#
.synopsis
Get a rooted path
.notes
Especially useful for .NET functions, which don't understand Powershell's $pwd, and instead have their own concept of the working directory, which is (in any normal case) always %USERPROFILE%. This means that if you do this:
cd C:\Windows
(New-Object System.Net.WebClient).DownloadFile("http://example.com/file.txt", "./file.txt")
... the file will be downloaded to %USERPROFILE%\file.txt, not C:\Windows\file.txt
#>
function Get-RootedPath {
[cmdletbinding()] param(
[Parameter(Mandatory=$true)] [String] $path
)
if (-not [System.IO.Path]::IsPathRooted($path)) {
$path = Join-Path -Path $pwd -ChildPath $path
}
try {
$rootedPath = [System.IO.Path]::GetFullPath($path)
}
catch {
Write-Error "Failed to validate path '$path'"
throw $_
}
return $rootedPath
}
<#
.synopsis
Download a URL from the web
.parameter url
The URL to download
.parameter outDir
Save the file to this directory. The filename will be the last part of the URL. This will make sense for a basic case like http://example.com/file.txt, but might be a little ugly for URLs like http://example.com/?product=exampleProduct&version=exampleVersion
.parameter outFile
Save the file to this exact filename.
.notes
Why not use Invoke-WebRequest or Invoke-RestMethod? Because those are not available before Powershell 3.0, and I still want to be able to use this function on vanilla Windows 7 (hopefully just before applying all updates and getting a more recent Powershell, but still.)
#>
function Get-WebUrl {
[cmdletbinding(DefaultParameterSetName="outDir")] param(
[parameter(mandatory=$true)] [string] $url,
@ -60,12 +117,15 @@ function Get-WebUrl {
[parameter(mandatory=$true,ParameterSetName="outFile")] [string] $outFile
)
if ($PScmdlet.ParameterSetName -match "outDir") {
$filename = [System.IO.Path]::GetFileName($url)
$outFile = "$outDir\$filename"
# If the URL is http://example.com/whatever/somefile.txt, the last URL component is somefile.txt
$lastUrlComponent = [System.IO.Path]::GetFileName($url)
$filename = Get-SanitizedFilename -fileName $lastUrlComponent
$outFile = Join-Path -Path $outDir -ChildPath $fileName
}
$outFile = [IO.Path]::GetFullPath($outFile)
$outFile = Get-RootedPath $outFile
Write-EventLogWrapper "Downloading '$url' to '$outFile'..."
(New-Object System.Net.WebClient).DownloadFile($url, $outFile)
return (get-item $outFile)
return (Get-Item $outFile)
}
<#
@ -506,6 +566,70 @@ function Install-Chocolatey {
Write-EventLogWrapper "Chocolatey install process completed:`r`n`r`n$chocoOutput"
}
<#
.notes
One nice thing about FF and Chrome is that you don't have to handle updates yourself - they both install services that update the browser for you
#>
function Install-Firefox {
[cmdletbinding()] param(
[ValidateSet("Standard","ESR")] [String] $edition = "Standard",
[String] $language = "en-US"
)
switch ($edition) {
"Standard" {$downloadPageUrl = 'https://www.mozilla.org/en-US/firefox/all/'}
"ESR" {$downloadPageUrl = 'https://www.mozilla.org/en-US/firefox/organizations/all'}
}
$osarch = Get-OSArchitecture
switch ($osarch) {
$ArchitectureId.amd64 {$os = 'win64'}
$ArchitectureId.i386 {$os = 'win'}
}
$firefoxIniFile = "${env:temp}\firefox-installer.ini"
try {
Write-EventLogWrapper "Finding download location for $edition edition of Firefox..."
$response = Invoke-WebRequest -Uri $downloadPageUrl
$downloadUrl = $response.ParsedHtml.getElementById($language).getElementsByClassName('download win')[0].getElementsByTagName('a') | Select -Expand href
$firefoxInstallerFile = Get-WebUrl -url $downloadUrl -outFile "${env:temp}\firefox-installer.exe"
$firefoxIniContents = @(
"QuickLaunchShortcut=false"
"DesktopShortcut=false"
)
Out-File -FilePath $firefoxIniFile -InputObject $firefoxIniContents -Encoding UTF8
Write-EventLogWrapper "Beginning Firefox installation process..."
$process = Start-Process -FilePath $firefoxInstallerFile.FullName -ArgumentList @("/INI=`"$firefoxIniFile`"") -Wait
if ($process.ExitCode -ne 0) {
throw "Firefox installer at $($firefoxInstallerFile.FullName) exited with code $($process.ExitCode)"
}
}
catch {
@($firefoxInstallerFile,$firefoxIniFile) |% { if ($_ -and (Test-Path $_)) { Remove-Item $_ } }
throw $_
}
Write-EventLogWrapper "Firefox installation process complete"
Remove-Item @($firefoxInstallerFile,$firefoxIniFile)
}
function Set-FirefoxOptions {
[cmdletbinding()] param(
[switch] $setDefaultBrowser
)
@($env:ProgramFiles,${env:ProgramFiles(x86)}) |% {
$testPath = "$_\Mozilla Firefox\firefox.exe"
if (Test-Path $testPath) {$ffPath = $testPath}
}
if (-not $ffPath) { throw "Could not find the Firefox install location." }
if ($setDefaultBrowser) {
Start-Process -FilePath $ffPath -ArgumentList @("-silent", "-setDefaultBrowser") -Wait -Verb RunAs
# This didn't appear to work:
# $defaultBrowserPath = "HKCU:\Software\Classes\http\shell\open\command"
# $defaultBrowserValue = '"{0}" -osint -url "%1"' -f $ffPath
# Set-ItemProperty -path $defaultBrowserPath -name "(default)" -value $defaultBrowserValue
}
}
function Set-UserOptions {
[cmdletbinding()] param(
[switch] $ShowHiddenFiles,

Loading…
Cancel
Save