Category: powershell

Using winget remotely behind proxy

Recently i started experimenting with win11 images and was surprised that microsoft added a linux style package manager that acted similar to apt, yum and others.

So i tried to use it to manage package on remote user workstatinos, and got into some problems.

Here i will try to recap the steps that I have done, to get it working in enterprise environment behind proxy.

Requirements:

  • Make sure you have latest powershell on the admin workstation
  • User workstation should have latest Windows 10/11
  • Powershell Remoting should be set up using GPO or some other method.

So at this point winget is still relatively fresh and undergoing changes, which means this instruction can become invalid at any point.

Lets get started and open psremoting session on the user workstation

Enter-PSSession -ComputerName workstation.contoso.com

The first problem is that winget is built to operate in interactive session, so it doesn’t use the system proxy that we can set using the netsh winhttp set proxy command, and other PowerShell related proxy settings. The only working solution is to set proxy in registry, using the below script

function Set-Proxy($proxy, $bypassUrls){
    $proxyBytes = [system.Text.Encoding]::ASCII.GetBytes($proxy)
    $bypassBytes = [system.Text.Encoding]::ASCII.GetBytes($bypassUrls)
    $defaultConnectionSettings = [byte[]]@(@(70,0,0,0,0,0,0,0,11,0,0,0,$proxyBytes.Length,0,0,0)+$proxyBytes+@($bypassBytes.Length,0,0,0)+$bypassBytes+ @(1..36 | % {0}))
    $registryPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
    Set-ItemProperty -Path $registryPath -Name ProxyServer -Value $proxy
    Set-ItemProperty -Path $registryPath -Name ProxyEnable -Value 1
    Set-ItemProperty -Path "$registryPath\Connections" -Name DefaultConnectionSettings -Value $defaultConnectionSettings
}
Set-Proxy "app-proxy.contoso.com:8080" "192.168.*;*.contoso.com"
You can paste the full script to PowerShell window and then edit to your needs, this should look like this

So now we need to somehow allow the traffic from the user workstation to the winget repo and product repos. I didn’t find a possibility to implement proxy authentication in this scenario, so i just used the whitelisting based on the following User-Agent strings:

Microsoft-CryptoAPI/* - this is for repo certificate checking
winget-cli* - this is for software download/repo list
*WindowsPowerShell/* - this is for initial app download

This is a tricky question security-wise, but for testing you can just whitelist the workstation while you update/install packages

If the user workstation is a Windows 10, you’ll need two additional prerequisites installed before the main packages.

Invoke-WebRequest -Uri https://github.com/microsoft/microsoft-ui-xaml/releases/download/v2.7.3/Microsoft.UI.Xaml.2.7.x64.appx -OutFile $env:TEMP\Microsoft.UI.Xaml.2.7.x64.appx
Add-AppxPackage -Path  $env:TEMP\Microsoft.UI.Xaml.2.7.x64.appx
Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx -OutFile $env:TEMP\Microsoft.VCLibs.x64.14.00.Desktop.appx
Add-AppxPackage -path $env:TEMP\Microsoft.VCLibs.x64.14.00.Desktop.appx

Now we need to download and install winget (Microsoft.AppInstaller) and Windows Package Manager Source (winget) (Microsoft.Winget.Source_8wekyb3d8bbwe)

Invoke-WebRequest -Uri https://github.com/microsoft/winget-cli/releases/latest/download/Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle -OutFile $env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Add-AppxPackage -Path $env:TEMP\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle
Invoke-WebRequest -Uri https://cdn.winget.microsoft.com/cache/source.msix -OutFile $env:TEMP\source.msix
Add-AppxPackage -Path $env:TEMP\source.msix

The second one should be installed automatically, but for some reason it wont, possibly something related to non-interactive session again.

Now we can try to call to winget (don’t forget --accept-source-agreements first time you run it, interactive Y/N isn’t working on remote session)

winget list --accept-source-agreements

After this you should be able to install / update the needed software. If something is not working, it’s most likely proxy related.

I cut out progress bar spam for this screenshot

Quick convert jpg to PDF one-liner

OS: Windows

Required software:

https://www.ghostscript.com/download.html

Spent a few hours before syntax was correct, so I felt I should share this.

gswin64c -dORIENT1=false -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=C:\Users\username\Desktop\somepdffile.pdf -c "<</Orientation 3>> setpagedevice" -f "C:\Program Files\gs\gs9.19\lib\viewjpeg.ps" -c "(C:\\Users\\username\\Desktop\\somejpgfile.JPG) << /PageSize 2 index viewJPEGgetsize 2 array astore  >> setpagedevice viewJPEG"

So, after installing GhostScript, open command prompt in C:\Program Files\gs\gs%version_number%\bin

The one-liner above converts jpg file to pdf with auto-size and rotation 90 degrees clockwise.

Can be modified to handle multiple jpg by duplicating string “(C:\Users\username\Desktop\somejpgfile.JPG) << /PageSize 2 index viewJPEGgetsize 2 array astore >> setpagedevice viewJPEG”

Batch change advanced vm settings using PowerCLI in VCenter

If you, for some reason, want to add a few settings to all / some group of vm’s in your environment, you can use the below script. It checks if values are already there and changes only when necessary.

To change settings, edit PSCustomObject Names/values, to change vm’s to apply changes to, edit “$vms = Get-VM vmname.contoso.com” filter.

Continue reading

Exchange scheduled message removal using search.

Recently i had a task to delete obsolete antispam email notification in our environment.

I made a bit of researching on the matter, and, alas, the tool MS suggested to use, ComplianceSearchAction -Purge, only supported deleting 10 messages per mailbox, though i had quite a lot of daily spam notification incoming on some of our accounts.

So, i decided i’ll use ComplianceSearch to purge mailboxes where 10 or less messages matched the criteria, and for others i use Search-Mailbox -DeleteContent commandlet.

So, below script will allow to do that on a regular basis.

Continue reading

Exchange – Convert shared mailbox to distribution group

Quite annoying task, especially taking into account that each of the members wants a copy of information from shared mailbox.
So, the following script will do the following
– Save Shared Mailbox into a variable 🙂
– Hide Shared Mailbox form GAL
– Remove all Shared Mailbox addresses and change it to GUID
– Change Shared Mailbox Name to GUID
– Create new DG with all the addresses of the orignal
– Add all who had access to Shared Mailbox as members of the DG
– Add all who had access to Shared Mailbox permission to Send As DG
– Copy All Content of Shared Mailbox to folder in the each of the personal mailboxes of the users who had access to the Shared Mailbox

Continue reading

VMWare PowerCLI – inventory report

This simple one-liner will give you main hardware and infrastructure information about vCenter vms.

Fields included:
Name – VM Name
PowerState – Powered On / Off
OS – OS Set on the VM profile
HWVersion – VM Hardware version
IPAddresses – all ip addresses (reported by VM Tools)
AdapterTypes – all network adapter types
DnsName – DNS Name from OS (reported by VM Tools)
ToolsVersion – VM Tools
ToolsStatus – VM Tools status

get-vm | select name, Powerstate,@{N="OS"; E={$_.Guest.OSFullName}},@{N="HWVersion"; E={$_.Version}},@{N="IPAddresses"; E={$_.Guest.IPAddress}},@{N="AdapterTypes"; Expression={(Get-NetworkAdapter $_).type}},@{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}},@{N="ToolsVersion"; E={$_.Guest.ToolsVersion}},@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsVersionStatus}} | FT name, Powerstate, OS, HWVersion, IPAddresses, AdapterTypes, DnsName, ToolsVersion, ToolsStatus
get-vm | select name, Powerstate,@{N="OS"; E={$_.Guest.OSFullName}},@{N="HWVersion"; E={$_.Version}},@{N="IPAddresses"; E={$_.Guest.IPAddress}},@{N="AdapterTypes"; Expression={(Get-NetworkAdapter $_).type}},@{N="DnsName"; E={$_.ExtensionData.Guest.Hostname}},@{N="ToolsVersion"; E={$_.Guest.ToolsVersion}},@{N="ToolsStatus"; E={$_.ExtensionData.Guest.ToolsVersionStatus}} | Export-Csv -Path E:\tmp\vcenter.hosts.csv -NoTypeInformation -UseCulture

Powershell script to monitor/reset a VCenter VM with a web service.

A few years back i had an old apache server on linux, who’s constant hangs were in need of restart, to keep him running. Also, normal restarts were not an option, system was unresponsive. It was unclear, what exactly generated these errors, and not my task to do.

Task was to automate this process.

Continue reading

Powershell change password warning for users (Fine-Grained Password Policy).

Microsoft Fine-Grained Password Policies is a great tool to divide password policies (for example for users and server accounts).

All scripts i have come by were not taking into account Fine-Grained Password Policies.

Continue reading

Powershell script to check if a file exists on a workstations in a domain OU.

Another useful script for an administrator, for example to check deployment status.

Script checks $path on the list of computers, that are taken from domain OU, and defined by a filter, and gives a friendly colored console output with additional information, like days workstation is offline.

Continue reading