Downloading/Installing Visual Studio 2019 with Powershell - visual-studio

I have this code. It is supposed to download visual studio via a powershell script
$url = "https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=professional&rel=16&utm_medium=microsoft&utm_source=learn.microsoft.com&utm_campaign=link+cta&utm_content=download+commandline+parameters+vs2019"
New-Item -Path 'C:\dev\pub\vs' -ItemType Directory -force
$downloadPath = "C:\dev\pub\vs"
$filePath = "C:\dev\pub\vs\vs_professional.exe"
#Invoke-WebRequest -URI $url -OutFile $filePath
$workloadArgument = #(
'--add Microsoft.Net.Component.4.7.1.SDK'
'--add Microsoft.VisualStudio.Component.Windows10SDK.17134'
'--add Microsoft.Net.Component.4.7.1.TargetingPack'
)
$optionsAddLayout = [string]::Join(" ", $workloadArgument )
$optionsQuiet = "--quiet"
$optionsLayout = "--layout $downloadPath"
$optionsIncludeRecommended = "--includeRecommended"
$vsOptions = #(
$optionsLayout,
$optionsIncludeRecommended,
$optionsAddLayout
$optionsQuiet
)
Start-Process -FilePath $filePath -ArgumentList $vsOptions
For some reason, Invoke-WebRequest isn't downloading the file it is supposed to be. If you go to the link, a file gets automatically downloaded (the correct file), but the cmdlet gives the wrong file. I was wondering how I can get this to download the correct .exe so I can use Start-Process.
Thanks.

The issue is that it's not a direct link to the "actual" installer. When you go to the "Download" page that you mentioned:
https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=professional&rel=16&utm_medium=microsoft&utm_source=learn.microsoft.com&utm_campaign=link+cta&utm_content=download+commandline+parameters+vs2019
The code displays the page, then the page kicks off a piece of javascript that makes the actual request to the "real" link (i.e. the website doesn't change, and all real links are all stored in a database somewhere).
To get the "real" link, start your web browser, open up the Developer Tools (F12). Go to the "Network" tab. Go to the "download" page that you have above. Wait till you get the download request. In the Network traffic, you should see one request for the vs_Professional.exe page. Then you can copy the link address to the direct download:
This gets you the direct link, which (caution) may change/break with different versions and releases, so you might have to get the new link a couple of times. The link I got for right now is:
https://download.visualstudio.microsoft.com/download/pr/e730a0bd-baf1-4f4c-9341-ca5a9caf0f9f/4358b712148b3781631ab8d0eea42af736398c8b44fba868b76cb255b3de7e7c/vs_Professional.exe

Related

create shelveset automatically in visual studio or using command prompt

I am wondering if there is anyway to create shelvesets (backup) automatically (e.g. every 1 hr) from open solutions from different workspaces in visual studio?
Here is a extension create a shelveset for the latest version of all pending changes automatically in VS Marketplace.
TFS Auto Shelve for Visual Studio 2015
By default it's 5 minute interval, you could set interval for 60 minutes to meet your needs.
If you dont want the requirement of having VS and a specific solution open, then there's this script I wrote a long time ago and still gets a lot of use.
<#
.DESCRIPTION
This script will create a shelveset for each workspace it finds in the form "WorkspaceName_dddHHmm"
(ex. 'MyWorkspace_Mon1300' for monday at 1PM/1300). It does NOT require Visual Studio to be running.
.NOTE
The intention is to run this as a Scheduled Task periodically. I run it every hour during my usual working
time, and an hour before and after. With the naming pattern it uses, this means I have a rolling week of
shelvesets that I can refer back to in case of hardware failure, mucking something up, getting work laptop
confiscated by TSA, etc. Its also good for teams to use for sharing code or to check on the progress of
noobs that may not know when to ask for help
#>
$ErrorActionPreference = 'Stop'
$Error.Clear()
Clear-Host
#the collection should be read from somewhere like $HOME\AppData\Roaming\Microsoft\VisualStudio\15.0_f40892c4\Team Explorer\TeamExplorer.config
#but this was easier. This URL is for Azure DevOps, for on premise, use the project collection url you can get from looking at the workitems.
$projectCollectionUrl = "https://yourOrgUrl.visualstudio.com"
try
{
$vsWherePath = Resolve-Path "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$tfExeRoot = & "$vsWherePath" -latest -products * -requires Microsoft.VisualStudio.TeamExplorer -property installationPath
$tfExePath = Join-Path $tfExeRoot "\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\tf.exe" -Resolve
$workspaces = [xml](& $tfExePath vc workspaces /collection:$projectCollectionUrl /format:xml)
$workspaceFolders = #($workspaces.Workspaces.Workspace.Folders.WorkingFolder.local)
$currentDate = (Get-Date).ToString("ddd_HHmm")
foreach($workspace in $Workspaces.Workspaces.Workspace)
{
$workspaceFolder = $workspace.Folders.WorkingFolder.local | Select-Object -First 1
if (-Not (Test-Path $workspaceFolder))
{
Write-Host "There is no workspace folder at $workspaceFolder" -ForegroundColor Red
continue
}
Set-Location $workspaceFolder
try
{
$shelveSetName = "AutoShelve_$($workspace.Name)_$currentDate"
& "$tfExePath" shelve $shelveSetName /noprompt /replace
}
catch
{
if ($_.Exception.Message -like "*There are no matching pending changes to shelve*")
{
Write-Host "There are no pending changes to shelve for workspace $workspaceFolder" -ForegroundColor Yellow
continue
}
throw
}
}
}
finally
{
Set-Location $PSScriptRoot
}

How to get the Dropbox folder in Powershell in Windows

Same question exists for Python here: How can I get the Dropbox folder location programmatically in Python?, or here for OSX: How to get the location of currently logined Dropbox folder
Same thing in Powershell. I need the path of DropBox to copy files to it (building a software and then copying it to dropbox to share with team).
This Dropbox help page tells us where this info is stored, ie, in a json file in the AppData of the user: https://www.dropbox.com/help/4584
function GetDropBoxPathFromInfoJson
{
$DropboxPath = Get-Content "$ENV:LOCALAPPDATA\Dropbox\info.json" -ErrorAction Stop | ConvertFrom-Json | % 'personal' | % 'path'
return $DropboxPath
}
The line above is taken from: https://www.powershellgallery.com/packages/Spizzi.Profile/1.0.0/Content/Functions%5CProfile%5CInstall-ProfileEnvironment.ps1
Note that it doesn't check if you've got a Dropbox business account, or if you have both. It just uses the personal one.
You can then use this base Dropbox folder to build your final path, for example:
$targetPath = Join-Path -Path (GetDropBoxPathFromInfoJson) -ChildPath 'RootDropboxFolder\Subfolder1\Subfolder2'
if (-not (Test-Path -Path $targetPath)) { throw "Path '$targetPath' not found!" }
--
Alternative way is using the host.db file, as shown on this page:
http://bradinscoe.tumblr.com/post/75819881755/get-dropbox-path-in-powershell
$base64path = gc $env:appdata\Dropbox\host.db | select -index 1 # -index 1 is the 2nd line in the file
$dropboxPath = [System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String($base64path)) # convert from base64 to ascii

I want to fetch the name of the latest updated folder at particular path of FTP server

Using this command I am able to get the latest updated folder in Unix
ls -t1 | head -1
But how can I get the same in FTP server from Windows?
I want to get the name of the latest updated folder at particular path of FTP server. Could any one please help?
There's no easy way to do this with Windows shell commands.
You can:
Use ftp.exe to execute ls /path c:\local\path\listing.txt to save a directory listing to a text file.
Exit ftp.exe.
Parse the listing and find the latest files. Not an easy task for Windows shell commands.
It would be a way easier with a PowerShell script.
You can use FtpWebRequest class. Though it does not have an easy way to retrieve structured directory listing either. It offers only ListDirectoryDetails and GetDateTimestamp methods.
See Retrieving creation date of file (FTP).
Or use a 3rd-party library for the task.
For example with WinSCP .NET assembly you can do:
param (
$sessionUrl = "ftp://user:mypassword#example.com/",
$remotePath = "/path"
)
# Load WinSCP .NET assembly
Add-Type -Path "WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions
$sessionOptions.ParseUrl($sessionUrl)
# Connect
$session = New-Object WinSCP.Session
$session.Open($sessionOptions)
# Get list of files in the directory
$directoryInfo = $session.ListDirectory($remotePath)
# Select the most recent file
$latest =
$directoryInfo.Files |
Where-Object { -Not $_.IsDirectory } |
Sort-Object LastWriteTime -Descending |
Select-Object -First 1
# Any file at all?
if ($latest -eq $Null)
{
Write-Host "No file found"
}
else
{
Write-Host "The latest file is $latest"
}
See full example Downloading the most recent file.
(I'm the author of WinSCP)

Not able to spawn off email message from windows search in powershell

I have a powershell script that is searching the Windows Search index directly for emails and files. I have the following code:
$searchme="my thing to find"
$sql="SELECT System.FileName, System.ItemPathDisplay, System.DateCreated, System.DateModified, system.itemurl, system.itemtypetext FROM SYSTEMINDEX WHERE Contains(System.FileName, '"+$searchme+"') OR Contains('"+$searchme+"')"
$adapter = new-object system.data.oledb.oleDBDataadapter -argumentlist $sql, "Provider=Search.CollatorDSO;Extended Properties=’Application=Windows’;"
$ds = new-object system.data.dataset
$adapter.Fill($ds)
foreach ($record in $ds.Tables[0].Rows)
{
$exeparams = $record[4]
write-host $exeparams
write-host $exeparams.split(":")[0]
if ($exeparams.split(":")[0] -eq "mapi15")
{
$exeparams2="mapi://" + $exeparams.substring(8)
}
write-host $exeparams
write-host "start"
$exe="start"
$exe+" "+$exeparams | Out-File 'file.txt' -encoding Unicode
write-host "start-process"
Start-Process $exeparams
Start-Process $exeparams2
write-host "andpersand process"
&$exe $exeparams
&$exe $exeparams2
write-host "dotnet"
$proc = [Diagnostics.Process]::Start($exeparams)
$proc.WaitForExit()
$proc = [Diagnostics.Process]::Start($exeparams2)
$proc.WaitForExit()
}
There are several "shell" calls because I was trying to figure out if it was a process spawning issue. Files work with no issue. Emails however fail with either No such interface if i leave mapi15, or Unspecified error if i change mapi15 to mapi. I believe that Open mails in outlook from java using the protocol "mapi://" may be the solution, but if it is I am not sure how to apply this in powershell. Thank you for your help.
Ok, that took more work than I expected, and I blame Office 2013 for it. Here's the short answer:
$exeparams2 = $exeparams -replace "^mapi15", "mapi"
& start $exeparams2
That is the code that now opens an email for me. That code did not do that yesterday, all it did is tell me:
Either there is no default mail client or the current mail client cannot fulfill the messaging request. Please run Microsoft Outlook and set it as the default mail client.
Infuriating is what this was, because I did have Outlook, in fact it was running, and was the default mail application for everything email related. This annoyed me, and sent me on a quest to figure out WTF was wrong, and if I could fix it. The answers to that are "I'm not real sure WTF was wrong, except maybe a naming change on MS's part", and "yes, yes I can fix it".
I finally found the fix that worked for me (and I believe that this is probably Office 2013/Office 365 specific) was found at the bottom of this thread:
https://social.technet.microsoft.com/Forums/office/en-US/64c0bedf-2bcd-40aa-bb9c-ad5de20c84be/cannot-send-email-with-microsoft-outlook-2010-64-bit-from-adobe-outlook-not-recognised-as?forum=outlook
The process is simple. Change 2 Registry Entries, then re-set your default mail application. Registry entries:
HKLM:\Software\Clients\Mail(default)
HKLM:\Software\Clients\Mail\Microsoft Outlook(default)
Change the value of (Default) from "Microsoft Outlook" to simply "Outlook".
After that I set Outlook to be the default for everything it could be ( in Win8 that's Control Panel > All Control Panel Items > Default Programs > Set Default Programs then select Outlook, and choose the first option to make it default for all extensions that it is registered for). Once that was done I was able to run the modified code above to launch an email that I had search the index for.

Powershell COM object Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED)

I am trying to use powershell to script some tasks within internet explorer. This involves downloading a file from a website after logging in to the site. I have one working test script, but the same code for the actual site gives me this error:
The '=' operator failed: The object invoked has disconnected from its clients. (Exception from HRESULT: 0x80010108 (RPC_E_DISCONNECTED)).
At U:\PowershellScriptProjectSFTP\test.ps1:71 char:22
+ $controlRef = <<<< $browserDoc.getElementByID($controlID)
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : OperatorFailed
$browserDoc
$ie = new-object -com "InternetExplorer.Application"
$ie.navigate("about:blank")
$ie.visible = $true
[System.Threading.Thread]::Sleep(2000)
$ie.navigate($URL)
#get controls
write-host "Getting Document"
$browserDoc=$ie.Document
write-host "Getting Email component"
$email = $browserDoc.getElementById("MainContent_userEmail")
write-host "Getting Password component"
$pass = $browserDoc.getElementById("MainContent_userPassword")
write-host "Getting Button component"
$login = $browserDoc.getElementById("MainContent_submitButton")
The actual error is occuring elsewhere in the code, which I have left out because it is doing the same thing as up here, but during the loop to ensure the page is done loading. This code has worked from the same machine on a different site, but both were .net aspx 2.0 sites.
Basically, once the internet explorer navigates to the specified url, powershell loses the ability to communicate with the object, and this error is followed by several InvokeMethodOnNull and PropertyNotFound errors (these I understand, they are a result of referencing $ie, which has become a null object, the entire problem I am trying to diagnose). I am running Windows 7. Microsoft claims to have a fix for this, but only for XP and Server 03 and 08.
Really, just any explaination for what causes this behavior is all I am looking for. As I said, this same code pointed to some websites works perfectly, and at others fails everytime.
Just ran into this myself and found that running the Powershell window "as administrator" fixed the problem.

Resources