Download-Files-TubesMedia-SearchAndDownloadFilesOnWebsite.psm1
<#
.EXTERNALHELP Download-Files-TubesMedia-SearchAndDownloadFilesOnWebsite.psm1-Help.xml #> function Invoke-FileDownload { param ( [Parameter(Mandatory = $true, Position = 1, HelpMessage = 'Provide correct URL like www.google.com')] [uri]$URL, [Parameter(Mandatory = $true, Position = 2, HelpMessage = 'Enter filename to search on website, you can use wilcards like: file*name*.jpg')] [SupportsWildcards()] [string]$Filename, [Parameter(HelpMessage = 'Enter full download path to folder.')] [string]$Path, [switch]$GetLink, [switch]$ListFoundedFiles, [Parameter(HelpMessage = 'Enter full alternate filename with exstension.')] [string]$NewFileName ) function Test-Admin { [CmdletBinding()] [OutputType([Boolean])] Param () $User = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() if ($User.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { return $true } return $false } function Get-UrlStatusCode { param ( [Parameter(Mandatory = $true)] [uri]$TestURL ) try { (Invoke-WebRequest -Uri $TestURL -UseBasicParsing -DisableKeepAlive -ErrorAction SilentlyContinue).StatusCode } catch [Net.WebException] { [int]$_.Exception.Response.StatusCode } } $IEcheck = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Internet Explorer\Main' -Name DisableFirstRunCustomize).DisableFirstRunCustomize if ($IEcheck -ne 2) { if (Test-Admin) { Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Internet Explorer\Main" -Name "DisableFirstRunCustomize" -Value 2 } else { return Write-Warning 'Internet Explorer was not run for first time, to fix this run Internet explorer or run this command again in elevated console.' }} if (($Filename -eq "*") -or ($Filename -eq "*.*")) { return Write-Warning 'Cannot provide only wildcard.' } if (($GetLink) -and ([System.Management.Automation.WildcardPattern]::ContainsWildcardCharacters($Filename))) { return Write-Warning '-GetLink switch must be used with exact filename without wildcards.' } if ($Filename.Substring(0, 1) -ne "*") { $Filename = "*" + $Filename } if (!$Path) { $Path = Get-Location } $DownloadWebPage = (Invoke-WebRequest "$URL").AllElements $FilesFinded = $DownloadWebPage.href -like "$Filename" if (!$FilesFinded) { return Write-Warning "No files found like $Filename" } $FileSelection = Split-Path -Path $FilesFinded -Leaf if ($FilesFinded.Count -gt 1) { $WEBPath = $FilesFinded.Split([Environment]::NewLine) | Select-Object -First 1 } else { $WEBPath = $FilesFinded } $statusCode = Get-UrlStatusCode -TestURL "$WEBPath" -ErrorAction SilentlyContinue if (($statusCode -eq 0) -or (!$statusCode)) { $WEBPath = "$URL" + $WEBPath $statusCode = Get-UrlStatusCode -TestURL "$WEBPath" if (($statusCode -eq 0) -or (!$statusCode)) { return Write-Error "Cannot find download link for searched file on the $URL" -Category InvalidResult } } if ($NewFileName) { $Filename = $NewFileName } else { $Filename = Split-Path $WEBPath -Leaf } $FullFilePath = Join-Path -Path $Path -ChildPath $Filename if ($GetLink -and $ListFoundedFiles) { Write-Warning "-GetLink switch should be used without -ListFoundedFiles switch." } if ($GetLink -and (!$ListFoundedFiles)) { $CleanPath = Invoke-WebRequest -Uri $WEBPath -MaximumRedirection 0 -ErrorAction SilentlyContinue $WEBPath = $CleanPath.Headers.Values | Select-String -SimpleMatch $Filename return $WEBPath } elseif ($ListFoundedFiles) { if ($FileSelection.Count -eq 1) { Write-Output "Only one file founded:" } return $FileSelection } else { Invoke-WebRequest -Uri $WEBPath -OutFile $FullFilePath -Method Get Write-Output "File downloaded to $FullFilePath" } } <# .EXTERNALHELP Download-Files-TubesMedia-SearchAndDownloadFilesOnWebsite.psm1-Help.xml #> function Invoke-MediaDownload { [CmdletBinding()] param ( [Parameter(Mandatory = $false, Position = 1, HelpMessage = 'Put pure link from site that you want to download it.')] [uri]$URL, [Parameter(Position = 4, HelpMessage = 'Use only if first method fails.')] [switch]$ytdlMethod, [Parameter(Position = 2)] [string]$Path = ($env:SystemDrive + $env:HOMEPATH + '\Videos\'), [Parameter(Position = 3)] [string]$AdditionalArguments, [Parameter(Position = 5)] [switch]$Help ) $WinGetEXE = 'winget.exe' $choco = 'choco.exe' $Downloader = 'yt-dlp.exe' $Downloader2 = 'youtube-dl.exe' function Test-Admin { [CmdletBinding()] [OutputType([Boolean])] Param () $User = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() if ($User.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { return $true } return $false } #region InstallNeeded function Get-NuGet { Write-Output "Getting NuGet package manager, answer 'Yes' if asked." $Repository = 'PSGallery' if (Get-PSRepository | Where-Object { $_.Name -eq $Repository -and $_.InstallationPolicy -ne "Trusted" }) { try { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.208 -Force -ErrorAction SilentlyContinue Set-PSRepository -Name $Repository -InstallationPolicy Trusted -ErrorAction SilentlyContinue } catch { throw $_ } } if (!(Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted -ErrorAction SilentlyContinue Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force -ErrorAction SilentlyContinue if (!(Get-PackageProvider -Name NuGet -ErrorAction SilentlyContinue)) { return Write-Error -Message 'Cannot get NuGet package manager. Please update PowerShell.' -Category NotInstalled } } } function Install-WinGet { $Xaml = Get-AppxPackage -Name 'Microsoft.UI.Xaml.2.7*' -ErrorAction SilentlyContinue if (!($Xaml)) { Write-Output 'Installing Microsoft.UI.Xaml.2.7.1' $url = 'https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.1' $zipFile = $env:TEMP + '\XamlTemp.zip' $tempFolder = New-Item -Path "$env:TEMP\XamlInst\" -ItemType Directory -Force -ErrorAction SilentlyContinue Invoke-WebRequest -Uri $url -OutFile $zipFile Expand-Archive -Path $zipFile -DestinationPath $env:TEMP\XamlInst\ -Force -ErrorAction SilentlyContinue if ([Environment]::Is64BitOperatingSystem) { Add-AppxPackage -Path $tempFolder\tools\AppX\x64\Release\Microsoft.UI.Xaml.2.7.appx -ForceApplicationShutdown -Update -ErrorAction SilentlyContinue Remove-Item -Path $zipFile -Force -ErrorAction SilentlyContinue Remove-Item -Path $tempFolder -Force -ErrorAction SilentlyContinue } else { Add-AppxPackage -Path $tempFolder\tools\AppX\x86\Release\Microsoft.UI.Xaml.2.7.appx -ForceApplicationShutdown -Update -ErrorAction SilentlyContinue Remove-Item -Path $zipFile -Force -ErrorAction SilentlyContinue Remove-Item -Path $tempFolder -Force -ErrorAction SilentlyContinue } if (!($Xaml)) { return Write-Warning 'Microsoft.UI.Xaml.2.7.1 not installed. Please update Windows.' } } $hasPackageManager = Get-AppxPackage -name 'Microsoft.DesktopAppInstaller' -ErrorAction SilentlyContinue if (!$hasPackageManager -or [version]$hasPackageManager.Version -lt [version]"1.10.0.0") { Write-Output 'Installing WinGet application manager.' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 if (!$hasPackageManager) { Add-AppxPackage -Path https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -InstallAllResources -ForceApplicationShutdown } else { Add-AppxPackage -Path https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -ForceUpdateFromAnyVersion -ForceApplicationShutdown } $releases_url = 'https://api.github.com/repos/microsoft/winget-cli/releases/latest' [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $releases = Invoke-RestMethod -uri $releases_url $latestRelease = $releases.assets | Where-Object { $_.browser_download_url.EndsWith('msixbundle') } | Select-Object -First 1 Write-Output "Installing winget from $($latestRelease.browser_download_url)" Add-AppxPackage -Path $latestRelease.browser_download_url } if (!(Get-Command -Name 'winget.exe' -ErrorAction SilentlyContinue) -and ($restart)) { Write-Warning '-restart switch is used, computer will restart in 5 secounds...' Restart-Computer -Force -Timeout 5 } if (!(Get-Command -CommandType Application -Name winget.exe -ErrorAction SilentlyContinue)) { return Write-Warning "WinGet still not active, please try to restart the computer and run this command again.`nIf you have fresh installed Windows please update it first." } } function Get-InstalledSoftware { [CmdletBinding(SupportsShouldProcess = $false)] [OutputType([System.Management.Automation.PSObject])] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String]$Name ) process { $UninstallKeys = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall", "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" $null = New-PSDrive -Name "HKU" -PSProvider "Registry" -Root "Registry::HKEY_USERS" $UninstallKeys += Get-ChildItem -Path "HKU:" -ErrorAction "SilentlyContinue" | ` Where-Object { $_.Name -match "S-\d-\d+-(\d+-){1,14}\d+$" } | ` ForEach-Object { "HKU:\$($_.PSChildName)\Software\Microsoft\Windows\CurrentVersion\Uninstall" } foreach ($UninstallKey in $UninstallKeys) { if ($PSBoundParameters.ContainsKey("Name")) { $WhereBlock = { ($_.PSChildName -match "^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$") -and ($_.GetValue("DisplayName") -like "$Name*") } } else { $WhereBlock = { ($_.PSChildName -match "^{[A-Z0-9]{8}-([A-Z0-9]{4}-){3}[A-Z0-9]{12}}$") -and ($_.GetValue("DisplayName")) } } $SelectProperties = @( @{ n = "Publisher"; e = { $_.GetValue("Publisher") } }, @{ n = "Name"; e = { $_.GetValue("DisplayName") } }, @{ n = "Version"; e = { $_.GetValue("DisplayVersion") } }, @{ n = "ProductCode"; e = { $_.PSChildName } }, @{ n = "BundleCachePath"; e = { $_.GetValue("BundleCachePath") } }, @{ n = "Architecture"; e = { if ($_.GetValue("DisplayName") -like "*x64*") { "x64" } else { "x86" } } }, @{ n = "Release"; e = { if ($_.GetValue("DisplayName") -match [RegEx]"(\d{4})\s+") { $matches[0].Trim(" ") } } }, @{ n = "UninstallString"; e = { $_.GetValue("UninstallString") } }, @{ n = "QuietUninstallString"; e = { $_.GetValue("QuietUninstallString") } }, @{ n = "UninstallKey"; e = { $UninstallKey } } ) $params = @{ Path = $UninstallKey ErrorAction = "SilentlyContinue" } Get-ChildItem @params | Where-Object $WhereBlock | Select-Object -Property $SelectProperties } } end { Remove-PSDrive -Name "HKU" -ErrorAction "SilentlyContinue" } } function Get-InstalledVcRedist { [CmdletBinding(SupportsShouldProcess = $false, HelpURI = "https://vcredist.com/get-installedvcredist/")] [OutputType([System.Management.Automation.PSObject])] param ( [Parameter(Mandatory = $false)] [System.Management.Automation.SwitchParameter]$ExportAll ) if ($PSBoundParameters.ContainsKey("ExportAll")) { Write-Verbose -Message "-ExportAll specified. Exporting all install Visual C++ Redistributables and runtimes." $Filter = "(Microsoft Visual C.*).*" } else { $Filter = "(Microsoft Visual C.*)(\bRedistributable).*" } Write-Verbose -Message "Matching installed VcRedists with: '$Filter'." $VcRedists = Get-InstalledSoftware | Where-Object { $_.Name -match $Filter } Write-Verbose -Message "Add Architecture property to output object." $VcRedists | ForEach-Object { if ($_.Name -contains "x64") { $_ | Add-Member -NotePropertyName "Architecture" -NotePropertyValue "x64" } } Write-Output -InputObject $VcRedists } function Test-VcRedist { $vcr = (Get-InstalledVcRedist).Name -like "*2010*x86*" if (!([boolean]$vcr)) { Write-Output 'Installing Microsoft Visual C++ 2010 Service Pack 1 Redistributable Package (x86)' $VcSetup = "$env:TEMP\vcredist_x86.exe" if (Test-Path $VcSetup -ErrorAction SilentlyContinue) { Remove-Item $VcSetup -Force -Recurse -ErrorAction SilentlyContinue } $VcURL = "https://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe" Invoke-WebRequest -Uri $VcURL -OutFile $VcSetup -Method Get -ErrorAction SilentlyContinue Start-Process -FilePath $VcSetup -ArgumentList "/passive /norestart" -Wait -ErrorAction SilentlyContinue Remove-Item $VcSetup -Force -ErrorAction SilentlyContinue $vcr = (Get-InstalledVcRedist).Name -like "*2010*x86*" if (!([boolean]$vcr)) { return Write-Warning "Installing Microsoft Visual C++ 2010 Service Pack 1 Redistributable Package (x86) failed.`nPlease update Windows and restart it and run this command again" } } } function Test-AllNeeded { Test-VcRedist if (!(Get-Command -CommandType Application -Name winget.exe -ErrorAction SilentlyContinue)) { $checkNuGeT = Get-PackageProvider -Name NuGet -ListAvailable -ErrorAction SilentlyContinue if (!$checkNuGeT) { Get-NuGet } else { Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.208 } Install-WinGet if (!(Get-Command -CommandType Application -Name winget.exe -ErrorAction SilentlyContinue)) { Write-Error 'WinGet not installed, if your Windows is fresh installed, please update it and restart the computer.' -Category NotInstalled } } if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue)) { Write-Output 'Getting yt-dlp video/audio download manager.' Start-Process -FilePath $WinGetEXE -ArgumentList "install yt-dlp --accept-package-agreements" -NoNewWindow -Wait if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue)) { return Write-Warning 'yt-dlp.exe not installed, restart the computer and start this command again' } else { Start-Process -FilePath $Downloader -ArgumentList '-U' -NoNewWindow -Wait } } if (!(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { Write-Output 'Getting youtube-dl video/audio download manager.' Start-Process -FilePath $choco -ArgumentList "install youtube-dl -y -f" -NoNewWindow -Wait } if (!(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { $here = (Get-Location).Path Invoke-FileDownload -URL https://yt-dl.org/ -Filename $Downloader2 -Path $here Start-Process -FilePath $Downloader2 -ArgumentList '-U' -NoNewWindow -Wait if (!(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { return Write-Warning "youtube-dl.exe not installed.`nTry to restart or update Windows then run this command again." } } else { Start-Process -FilePath $Downloader -ArgumentList '-U' -NoNewWindow -Wait } } #endregion InstallNeeded #region check if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue) -or !(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { if (!(Get-Command -Name $choco -ErrorAction SilentlyContinue)) { if (!(Get-Command -Name choco.exe -ErrorAction SilentlyContinue)) { Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) } } if (Get-Command -Name $choco -ErrorAction SilentlyContinue) { Start-Process -FilePath $choco -ArgumentList "install yt-dlp -y -f --nocolor --no-progress" -NoNewWindow -Wait Start-Process -FilePath $choco -ArgumentList "install youtube-dl -y -f --nocolor --no-progress" -NoNewWindow -Wait if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue) -or !(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { Test-AllNeeded; if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue) -or !(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { return Write-Error 'Cannot install needed files. Try to update Windows.' -Category NotInstalled }} } else { Test-AllNeeded; if (!(Get-Command -Name $Downloader -ErrorAction SilentlyContinue) -or !(Get-Command -Name $Downloader2 -ErrorAction SilentlyContinue)) { return Write-Error 'Cannot install needed files. Try to update Windows.' -Category NotInstalled }} } #endregion check if (!$URL -and !$Help) { return Write-Error 'Must specify the URL for video download.' -Category OperationStopped } if ($Help) { if ($ytdlMethod) { Write-Output '' Start-Process -FilePath $Downloader2 -ArgumentList "--help" -NoNewWindow -Wait Write-Output '' } else { Write-Output '' Start-Process -FilePath $Downloader -ArgumentList "--help" -NoNewWindow -Wait Write-Output '' } return Write-Warning 'If you get an error when try to download media (livestream or something unusual) use -AdditionalArguments and put the switch from this help like -AdditionalArguments "--SomeSwitch".' } if ($ytdlMethod) { $Filename = Read-Host -Prompt "File will be dowloaded at $Path`nPlease enter the filename for video file" if ($Filename -like '') { return Write-Error "With youtube-dl method filename must be entered." -Category InvalidData } $arguments = "$URL -o $Path$Filename.mp4 " if ($AdditionalArguments) { $arguments = $arguments + $AdditionalArguments } Write-Output '' Start-Process -FilePath $Downloader2 -ArgumentList $arguments -NoNewWindow -Wait Start-Process -FilePath $Downloader2 -ArgumentList '-U' -WindowStyle Hidden Write-Output '' } else { $arguments = "$URL -P$Path " if ($AdditionalArguments) { $arguments = $arguments + $AdditionalArguments } Write-Output '' Start-Process -FilePath $Downloader -ArgumentList $arguments -NoNewWindow -Wait Start-Process -FilePath $Downloader -ArgumentList '-U' -WindowStyle Hidden Write-Output '' } } |