public/mods/ubuntu/az/SSHKeyAdd/AddSSHKeySelinium.ps1
<#
This script uses Selenium WebDriver to automate the process of adding an SSH key to an Azure DevOps organization. It navigates to the Azure DevOps SSH keys page, finds the "New" button and clicks it, fills in the SSH key name and content, and then navigates to the "Save" button and clicks it. If the "New" button is not found, it prints "New button not found". #> # Parameters for the script: organization name, SSH key name, and SSH key content param($organization, $sshaKeyName, $sshaKeyContent) $ErrorActionPreference = "Stop" $blue = "`e[5;36m" $reset = "`e[0m"; function getAssemblyLastVersion ([string] $assembly, $files) { $assemblyExtension = $assembly.Substring($assembly.Length - 4) ##remove extension from assembly $allFiles = $files | Where-Object { $_.Name -like "*$assembly" -and $_.DirectoryName -notlike "*netstandard*" } #| Copy-Item -Destination $packageDir -Force $assembly = $assembly.Substring(0, $assembly.Length - 4) $versionedPaths = $allFiles | ForEach-Object { # Extract version (e.g., 'net8.0', 'net8.0.11', 'net9.0') from the path if ($_ -match ('\\lib\\(net[\d\.]+)\\' + $assembly + '\' + $assemblyExtension)) { [PSCustomObject]@{ Path = $_ Version = [version]($matches[1].Replace('net', '')) } } } # Find the highest version $highestVersionPath = $versionedPaths | Sort-Object Version -Descending | Select-Object -First 1 $highestVersionPath.Path.FullName } function getExeLastVersion ([string] $assembly, $files) { $assemblyExtension = $assembly.Substring($assembly.Length - 4) ##remove extension from assembly $allFiles = $files | Where-Object { $_.Name -like "*$assembly" -and $_.DirectoryName -notlike "*netstandard*" } #| Copy-Item -Destination $packageDir -Force $assembly = $assembly.Substring(0, $assembly.Length - 4) $versionedPaths = $allFiles | ForEach-Object { # Extract version (e.g., 'net8.0', 'net8.0.11', 'net9.0') from the path if ($_ -match ('\\driver\\(win[\d\.]+)\\' + $assembly + '\' + $assemblyExtension)) { [PSCustomObject]@{ Path = $_ Version = ($matches[1].Replace('win', '')) } } } $is64Bit = ([Environment]::Is64BitOperatingSystem) if ($is64Bit) { $versionedPaths = $versionedPaths | Where-Object { $_.Path.FullName -like "*win64*" } } else { $versionedPaths = $versionedPaths | Where-Object { $_.Path.FullName -like "*win86*" } } # Find the highest version $highestVersionPath = $versionedPaths | Sort-Object Version -Descending | Select-Object -First 1 $highestVersionPath.Path.FullName } Write-Host " Start" $packageDir = "$PSScriptRoot\assemblies" $packageDirTmp = "$packageDir\tmp" ## get current edge version # Install Selenium.WebDriver.MSEdgeDriver $nodePath = "$packageDir\nuget.exe" ## create tmp folder $packageDirTmp = "$packageDir\tmp\WebDriver" Write-Host " Install Selenium.WebDriver $blue" New-Item -Path $packageDirTmp -Force -ItemType Directory | Out-Null & $nodePath install Selenium.WebDriver -OutputDirectory $packageDirTmp -Source https://api.nuget.org/v3/index.json | Out-Null $files = Get-ChildItem -Path $packageDirTmp -Recurse $assemblyToCopy = getAssemblyLastVersion -assembly "WebDriver.dll" -files $files ##Copy the assembly to the assemblies folder Copy-Item -Path $assemblyToCopy -Destination $packageDir -Force ##remove Selenium.WebDriver from the tmp folder Remove-Item -Path $packageDirTmp -Recurse -Force $packageDirTmp = "$packageDir\tmp\MSEdgeDriver" Write-Host " Install Selenium.WebDriver.MSEdgeDriver $blue" New-Item -Path $packageDirTmp -Force -ItemType Directory | Out-Null & $nodePath install Selenium.WebDriver.MSEdgeDriver -OutputDirectory $packageDirTmp -Source https://api.nuget.org/v3/index.json | Out-Null $files = Get-ChildItem -Path $packageDirTmp -Recurse $assemblyToCopy = getExeLastVersion -assembly "msedgedriver.exe" -files $files ##Copy the assembly to the assemblies folder Copy-Item -Path $assemblyToCopy -Destination $packageDir -Force ##remove Selenium.WebDriver from the tmp folder Remove-Item -Path $packageDirTmp -Recurse -Force $packageDirTmp = "$packageDir\tmp" Remove-Item -Path $packageDirTmp -Recurse -Force # # Paths to WebDriver.dll and WebDriver.Support.dll $dll1Path = Join-path -path (Join-path -path $PSScriptRoot -ChildPath 'assemblies') -ChildPath 'WebDriver.dll' # # Load the WebDriver and WebDriver.Support assemblies Add-Type -Path $dll1Path # Add-Type -Path $dll2Path $seleniumManagerPath = "$packageDir\msedgedriver.exe" # Create EdgeDriver object to control Microsoft Edge Write-Host " Create EdgeDriver object to control Microsoft Edge `n`r" Write-Host "######################" # Create EdgeOptions object to customize EdgeDriver's behavior $edgeOptions = New-Object OpenQA.Selenium.Edge.EdgeOptions $edgeOptions.AddExcludedArgument("--enable-logging"); # $edgeOptions.AddArguments("headless","log-level=3") $Edge = New-Object OpenQA.Selenium.Edge.EdgeDriver -ArgumentList $seleniumManagerPath, $edgeOptions # Navigate to the Azure DevOps SSH keys page $Url = "https://dev.azure.com/$organization/_usersSettings/keys" Write-Host "######################" Write-Host "`n This tool uses Selenium to add SSH keys to Azure DevOps organizations" Write-Host " Currently the API doesn't support the operation (yeah , its ugly but hey ..it works)" $Edge.Url = $Url Write-Host "`n Launching $Url ...`n Hit [Return] to continue when after login and the page refreshes completely" # Wait for user to log in Read-Host # Find the New button and click it ( Devops last version=> 2023 , if find element throw exception is because is the old devops version) $elementSaveButtonNewVersion = $null try { $elementSaveButtonNewVersion = $Edge.FindElement([OpenQA.Selenium.By]::CssSelector("[aria-roledescription='button']")); $elementSaveButtonNewVersion.Click(); } catch { $elementSaveButtonNewVersion = $null $elementSaveButtonNewVersion = $Edge.FindElement([OpenQA.Selenium.By]::CssSelector("[command='add']")); $elementSaveButtonNewVersion.Click(); } if ($null -ne $elementSaveButtonNewVersion) { Start-Sleep -Seconds 5 # Fill in the SSH key name and content $element = $Edge.SwitchTo().ActiveElement(); $element.SendKeys($sshaKeyName) $element.SendKeys([OpenQA.Selenium.Keys]::Tab) $element = $Edge.SwitchTo().ActiveElement(); $element.SendKeys($sshaKeyContent) # Navigate to the save button and click it $element.SendKeys([OpenQA.Selenium.Keys]::Tab) $element = $Edge.SwitchTo().ActiveElement(); if ($element.Text -ne "Save") { $element.SendKeys([OpenQA.Selenium.Keys]::Tab) $element = $Edge.SwitchTo().ActiveElement(); } [Console]::Beep() Write-Host " Hit return to save the SSH key" Read-Host if ($null -ne $element) { $element.Click(); } Write-Host " SSH key submitted !`n" Write-Host " Validate if everything is Ok and hit return to exit" Read-Host $Edge.Quit(); } else { Write-Host "New button not found" } |