Powershell download to specific folder without knowing file name - powershell

I'm creating a Powershell script to download the latest version of a bunch of utilities. For some I know the URL and file name so this works:
$url = "https://download.sysinternals.com/files/SysinternalsSuite.zip"
$file = "SysinternalsSuite.zip"
$webclient.DownloadFile("$url","$storageDir\$file")
For some I just know the URL. For these I just know how to open it in the browser and file file is downloaded to the browsers download location.
$url = "https://toolslib.net/downloads/finish/1-adwcleaner/"
Start-Process "chrome.exe" "$url"
Is there any way to find the name of the file that was downloaded so it can be moved to $storageDir?
Alternately, is there a way to temporarily change a browsers default download location from inside the script and change it back at the end of the script? I'm not locked to any specific browser?

Related

Expand-Archive odd errors

I am trying to get at some data in an Autodesk Revit file, which is just a ZIP under the skin. I can use 7zip to extract but I am hoping to automate things with all native PS or Windows. I tried Expand-Archive after I renamed the RVT file to ZIP, but Expand-Archive has an odd error. The code is
Expand-Archive -path:'C:\RevitVersionTest\22-PLUMB-CLR-RECTANGULAR.zip' -destinationPath:'C:\Revit Fam'
And the error is
New-Object : Exception calling ".ctor" with "3" argument(s): "End of Central Directory record could not be found."
The file is corrupt. Re-download (or obtain) the ZIP file.
Background: I landed here having experienced the same error downloading a ZIP from Google Drive through a private link:
Invoke-WebRequest -Uri $zipFile -OutFile "$destPath\myZip.zip"
...then using the command:
Expand-Archive c:\a.zip -DestinationPath c:\a`
The file downloaded but it wouldn't extract. I downloaded through the browser using the UI, and then compared the download file sizes. Sure enough, the downloaded ZIP was corrupted. When I updated the URL to a Google Docs link directly to the file (that's public with permission), the ZIP then downloaded and extracted correctly.
Hence, comments under the question alluding to the file being corrupt are correct.

Powershell to find machine that created a file

I have a script that monitors the filesystem using FileWatcher.IO in Powershell.
Currently it finds the user that made the file with:
$owner = (Get-Acl $path).Owner
And it finds the computer that the file was made on with:
$Computer = get-content env:computername
But I'd also like to obtain what machine the file was created from. For instance, if a user is logged into a terminal server, I can see the file is made on the terminal server. But I want to know the host name of the local machine that made the file on the terminal server.
Is this possible? I've been searching the msdn PSEventArgs Class page without much success.
That information is not going to be stored in the file or its metadata, so no there's no straightforward way to get at it.
By the way, you can just use $env:computername directly as a variable; there's no need to use Get-Content.

Boxstarter or PowerShell command to change "Opens With" properties

I'm trying to develop my own Boxstarter script for spinning up new machines. I just realized that I'd really like to add a line that will change default applications to open certain file types. For example, I want to open .txt files with Notepad++. I know how to do this by right-click the file and checking it's properties, but is there a line I can add to my Boxstarter script that will do it? Or, since Boxstarter is basically a special set of PowerShell commands, is there a PowerShell command I can invoke directly to change the opens with property? I did some searching, and most of the results were about how to get PowerShell to open something, not change the opens with property. The rest were all about how to open PowerShell.
Another similar, but not quite the same, way to go about this is to change the file association you want to associate with a particular applicaition. Chocolatey includes some helper commands to do this and is therefore available to your Boxstarter package. Here is an excerpt from one of my Boxstarter packages:
Install-ChocolateyFileAssociation ".txt" "$env:programfiles\Sublime Text 2\sublime_text.exe"
Install-ChocolateyFileAssociation ".dll" "$($Boxstarter.programFiles86)\jetbrains\dotpeek\v1.1\Bin\dotpeek32.exe"
So now double clicking on any text file opens sublime or any dll opens dotpeek.
But I agree. Its still helpful to be able to add to the "Open With..." list.
Thanks to #Raf for pointing me in the right direction. Here's the code to change the OpensWith property of .txt files:
$principal = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
$key = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$acl = $key.GetAccessControl()
$right = "SetValue"
$denyrule = New-Object System.Security.AccessControl.RegistryAccessRule($principal,$right,"DENY")
$ret = $acl.RemoveAccessRule($denyrule)
$ret = $key.SetAccessControl($acl)
Set-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice -Name ProgId -Value Applications\notepad++.exe
Slightly modified from an answer in the TechNet forums.
I haven't figured out if there's a boxstarter shortcut for this, but changing the ACL rules was the key. Without it, you don't have the proper access to change this particular registry item. Even when I tried running Powershell as Admin and made sure I had all the right permissions on the UserChoice key (both the administrator account and my user account had Full Control), I kept getting an error that the Requested registry access is not allowed.

Powershell get latest on a working folder?

I am trying to get latest on a specific folder and was wondering how I would do this. I have been reading the MSDN documentation about the Workspace class but unfortunately it doesn't seem to provide any information about how I would go about getting latest of a specific folder.
For example, I have a single workspace but with multiple working folders. My PowerShell script can get latest but only at workspace level. Is it possible to get it from a working directory level or at a particular folder level?
Thanks in advance, DS.
EDIT
I believe this is possible as power tools is able to do it via right clicking a folder and getting latest. Ideally, want to replicate this.
http://msdn.microsoft.com/en-us/library/Microsoft.TeamFoundation.VersionControl.Client.Workspace.aspx
The below shows my script in practice..
$tfs = .\tfs-get-instance.ps1 -uri $uri
$vcs = $tfs.TfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
[psobject]$workspace = $vcs.GetWorkspace([System.Environment]::MachineName, [System.Environment]::UserName)
$workspace.Map($sourceFolder, $localFolder)
$result = $workspace.GetLocalItemForServerItem($sourceFolder);
if ($result -ne "")
{
echo $result
}
You should be able to use the Workspace.Get Method (String[], VersionSpec, RecursionType, GetOptions) to get what you want.
On the other hand, if you don't necessarily want to do it using the .NET objects, you could let tf.exe do the actual work, like the following:
& $TfExePath workfold /map "$codePath" "$LocalFolderPath" /collection:"$tfCollection" /workspace:$workspaceName
& $TfExePath get "$codePath" /version:$ChangeSet /force /overwrite /all /recursive $workspaceName
On the other hand, if you have the TF PowerTools installed you should also have PowerShell cmdlets for working with TFS. I have never used them, but I'm guessing you should be able to use them instead of using tf.exe if you want to. I would probably go for the PowerShell cmdlets in the power tools if they fill your need.

Trying to download a zip file from a weblink with powershell

Ok, I am trying to download a file off of a web link that we use with powershell. I am downloading a zip file where the begining of the name is always the same, but the the middle part will change based off of the version number of the zip. I have been able to get the file to download when I use the fully qualified web address and have the file name hard coded into the script. I have tried every version of using the wild cards to get all the most common version of the zip, but it errors out saying that it can't find the file on there server. This is the code that I have already, and any help would be greatly appreciated since I feel like I am at a wall with it.
$url = 'http://blah/blah/blah/My File Name 11.1111.11.zip'
$localFileName = 'C:\temp\MYzip.zip'
Invoke-WebRequest $url -UseDefaultCredentials -OutFile $localFileName
If the site has directory browsing enabled (unlikely unless you have control of the site and can turn it on), you can do this:
$url = 'http://blah/blah/blah/'
$wr = iwr $url
$filename = $wr.Links.href | Where {$_ -match 'My File Name.*?\.zip'}
$wr = iwr "$url/$filename"
If the site doesn't have directory browsing enabled then surely it has a page with a link to the ZIP file on it. Download that page and use the same $wr.Links.href trick to get all the links and look for the one that matches "My File Name.*?.zip".