Install winget by the command line (powershell) - windows

I'm trying to write a PowerShell script to setup windows dev machines. I want to use winget but I don't see any easy way just to install winget using the commandline. You have to either use the windows store or download the msxibundle from github.
Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/download/v1.3.2691/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -OutFile .\MicrosoftDesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Both of these require user's interaction instead of just running the script and walking away. Is there a better way? Thanks.

I devised a somewhat different approach, which installs the latest version:
# get latest download url
$URL = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
$URL = (Invoke-WebRequest -Uri $URL).Content | ConvertFrom-Json |
Select-Object -ExpandProperty "assets" |
Where-Object "browser_download_url" -Match '.msixbundle' |
Select-Object -ExpandProperty "browser_download_url"
# download
Invoke-WebRequest -Uri $URL -OutFile "Setup.msix" -UseBasicParsing
# install
Add-AppxPackage -Path "Setup.msix"
# delete file
Remove-Item "Setup.msix"

Using Windows PowerShell, not PowerShell Core, there's a command to help: Add-AppXPackage:
Add-AppXPackage -Path .\MicrosoftDesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Should allow you to install the package.
Hope this helps

Related

Using Invoke-restmethod gives "access to the path <path> is denied

I am trying to send a file via multipart formdata via invoke-restmethod. I don't have write permmision on the server but type filename works fine
My command is Invoke-RestMethod -Uri url -Method Post -infile file
Maybe file is not available in the PowerShell if its on a network location or if it is read only.
The read only problem is described here: https://www.reddit.com/r/PowerShell/comments/pwhsw2/invokerestmethod_method_put_infile_doesnt_work/
basically it is changing permissions as PowerShell has bug here:
Set-ItemProperty -Path <path> -Name IsReadOnly -Value $False
Then try again. If you can't change permissions you might switch to PowerShell 7

Getting error message when trying to run a powershell script that performs a silent install of an application

I am trying to perform a silent install of an application. (I'm doing this so that I can deploy it silently to other users in our domain)
The program I'm trying to silently install is OpenVPN. Here is the PowerShell script that I'm currently attempting to run.
$Computer = Read-Host -Prompt 'Enter the Computer Name you are accessing'
########## Install Software On PC ##########
New-Item -ItemType directory -Path "\\$Computer\c$\temp\openVPN"
Copy-Item "Z:\(15) IT\VPN\openvpn-install-2.4.8-1602-Win7.exe" "\\$Computer\c$\temp\openVPN" -Recurse
Write-Host "Installing openVPN on $Computer"
Invoke-Command -ComputerName $Computer -ScriptBlock {Start-Process "c:\temp\openVPN\openvpn-install-2.4.8-1602-Win7.exe" -ArgumentList "/q" -Wait}
Invoke-Command -ComputerName $Computer -ScriptBlock {Start-Process "c:\temp\openVPN\openvpn-install-2.4.8-1602-Win7.exe" -ArgumentList "/q" -Wait}
########## Remove temporary files and folder on each PC ##########
Write-Host "Removing Temporary files on $Computer"
$RemovalPath = "\\$Computer\c$\temp\openVPN"
Get-ChildItem -Path $RemovalPath -Recurse | Remove-Item -Force -Recurse
Remove-Item $RemovalPath -Force -Recurse
But I am receiving a couple of error messages when I run the script. The first error I encounter is that it says is
Copy-Item : Cannot find path 'Z:\(15) IT\VPN\openvpn-install-2.4.8-1602-Win7.exe' because it does not exist
(It does exist) And then the 2nd error I receive is
Connecting to remote server (Computer Name) failed with the following error message : The client cannot connect to the destination specified in the request.
Any help is appreciated!

Acces Denied: How can I create a powershell script that deploys IIS websites from Visual Studio post build event command line

I am trying to use the Web Administration module in a powershell script to deploy a handful of IIS websites and application pools using the visual studio post build event command line. When I run the script without using the web administration module the script succeeds, however I get an access denied error when they are included.
I have visual studio running as administrator
I have tried all sorts of flavor of setting the execution policy, but right now this is what I have (I have tried running both 32 and 64 bit versions of powershell):
cd $(ProjectDir)
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File "SetupLocalEnvironment.ps1" 2> nul
Looking for some assistance as my research is starting to reach the fruitless point. Thanks!
Here is the powershell script:
Import-Module WebAdministration
$FNMAWorkSpaceDirectory = "x"
# Do not edit below
Remove-Website -Name EDI
Remove-Website -Name WebAPI
Remove-WebAppPool -Name EDIAppPool
Remove-WebAppPool -Name WebAPIAppPool
New-WebAppPool EDIAppPool
New-WebSite -Name EDI -Port 124 -PhysicalPath "thePath" -ApplicationPool "thePool"
New-WebBinding -Name "EDI" -Protocol "https" -IPAddress "*" -Port 125
New-WebAppPool WebAPIAppPool
New-WebSite -Name WebAPI -Port 123 -PhysicalPath "thePath" -ApplicationPool "WebAPIAppPool"
Set-Location Cert:\LocalMachine\My
$certHash = (Get-ChildItem -DnsName "theCertName").Thumbprint
$guid = [guid]::NewGuid()
$Command = "http add sslcert ipport=0.0.0.0:125 certhash=$certHash appid={$guid}"
$Command | netsh
exit

How do I use PowerShell to remove registry keys from a remote computer?

I am trying to use PowerShell to remove profiles and associated registry entries on remote computers. The account I am using has administrator permissions on the remote computers. I have no trouble pulling the SIDs of the accounts or deleting the profile. My problem comes when trying to remove the registry key for the account located at HKLM:\SOFTWARE\Microsoft\'Windows NT'\CurrentVersion\ProfileList. There is a key for every SID and I want to remove the ones that match the profiles I am deleting.
This is what I have tried so far:
Enter-PSSession $comp
Remove-Item "HKLM:\SOFTWARE\Microsoft\'Windows NT'\CurrentVersion\ProfileList\$SID"
Exit-PSSession
This got the following result:
Remove-Item : Cannot find path 'HKLM:\SOFTWARE\Microsoft\'Windows
NT'\CurrentVersion\ProfileList\S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1000' because it does not exist.
If I run the same command on the local machine, the key is deleted successfully.
I also tried:
Enter-PSSession $comp
Remove-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList' -name $SID
Exit-PSSession
Which returned the following:
Remove-Itemproperty : Requested registry access is not allowed.
I have also tried using invoke-command to run the exact same command that works locally and I get the same error.
Is there something I am missing? Can any of you kind folks point out what I am doing wrong? I would really like to do this with built-in commands rather than installing a third party module if possible.
If you are looking to remove user profiles and cannot use a third party tool I would recommend using the CIM classes.
Get-CimInstance -ClassName Win32_UserProfile -Filter "SID = 'S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1000'" -ComputerName $comp | Remove-CIMInstance -WhatIf
If you do not have winrm enabled or configured you can fallback on WMI.
Get-WmiObject -Class WIN32_UserProfile -Filter "SID = 'S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX-1000'" -ComputerName $comp | Remove-WmiObject -WhatIf
This will get not only the registry key but also the folders associated with the profile.

Running a remote PowerShell script with a Git command in it results in NativeCommandError

I am getting an error while executing a remote PowerShell script. From my local machine I am running a PowerShell script that uses Invoke-Command to cd into a directory on a remote Amazon Windows Server instance, and a subsequent Invoke-Command to execute script that lives on that server instance. The script on the server is trying to git clone a repository from GitHub. I can successfully do things in the server script like "ls" or even "git --version". However git clone, git pull, etc. result in the following error:
Cloning into 'MyRepo'... + CategoryInfo : NotSpecified: (Cloning into 'MyRepo'...:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError
This is my first time using PowerShell or a Windows Server. Can anyone provide some direction on this problem.
The client script:
$s = new-pssession -computername $server -credential $user
invoke-command -session $s -scriptblock { cd C:\Repos; ls }
invoke-command -session $s -scriptblock { param ($repo, $branch) & '.\clone.ps1' -repository $repo -branch $branch} -ArgumentList $repository, $branch
exit-pssession
The server script:
param([string]$repository = "repository", [string]$branch = "branch")
git --version
start-process -FilePath git -ArgumentList ("clone", "-b $branch https://github.com/MyGithub/$repository.git") -Wait
I've changed the server script to use start process and it is no longer throwing the exception. It creates the new repository directory and the .git directory but doesn't write any of the files from the github repository. This smells like a permissions issue. Once again invoking the script manually (remote desktop into the amazon box and execute it from powershell) works like a charm.
Anytime you're calling an external executable from PowerShell, I highly recommend using Start-Process. The Start-Process cmdlet handles command line arguments much better, as compared to calling the executables directly.
Important: You must also be aware that if you run two separate Invoke-Command commands (unless you're using the -Session parameter) that you will be operating in two completely distinct PowerShell Remoting sessions! If you use the cd (aka. which is an alias for Set-Location) command, the results of that command will not persist into the new session when you run your Git command.
$GitExe = '{0}\path\to\git.exe' -f $env:SystemDrive;
$ArgumentList = 'clone "c:\path\with spaces\in it"';
Start-Process -FilePath $GitExe -ArgumentList $ArgumentList -Wait -NoNewWindow;
There is also a -WorkingDirectory parameter on the Start-Process cmdlet, that allows you to specify the Working Directory for a process. Instead of using the Set-Location cmdlet to set the "current directory" of the PowerShell session, you're probably better off specifying the full path to the working directory for the process. For example, let's say you had a Git repository in c:\repos\repo01, and your Git exe was in c:\git. You shouldn't worry so much about where PowerShell's "current directory" is, and rather focus on specifying the full paths to:
The Git executable
The Git repositories
Here's an example of how to achieve that:
Start-Process -FilePath c:\git\git.exe -ArgumentList 'clone "c:\repos\repo01" "c:\repos\repo02"" -Wait -NoNewWindow;
Note: I don't know the Git commands, but you should be able to adjust the value of the $ArgumentList variable above, to make it work for you. In PowerShell, you can put double-quotes inside of single-quotes, without having to worry about escaping them.

Resources