Batch file - pull commands from web resource - windows

I've tried several solutions to no avail, but am looking for a solution as to create a batch file that will run any commands located in a remote .txt file located on a website.
For example, somebody clicks on a .bat and the .bat retrieves a list of commands from www.example.com/command.txt, and then runs the contents of the .txt as if the commands were specified explicitly in the original .bat file. I am not opposed to using PowerShell or VBScript.

In PowerShell you can do this: iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
i.e. this downloads and runs the PowerShell script: https://chocolatey.org/install.ps1
Explanation
New-Object System.Net.WebClient creates a new instance of the .Net web client.
DownloadString('https://chocolatey.org/install.ps1') invokes the web client's Download method to pull back the text from this script (see https://msdn.microsoft.com/en-us/library/fhd1f0sw(v=vs.110).aspx).
iex is an alias for invoke-expression. This runs the downloaded string as if it were a command; i.e. causes PowerShell to execute the remote script.
Simpler Version
While the Chocolatey install script's an impressive 1 liner, the expanded version below may be simpler to understand (though ultimately does exactly the same as the above; just split over several lines).
$scriptUri = 'https://chocolatey.org/install.ps1'
$webClient = New-Object -TypeName 'System.Net.WebClient'
$scriptAsString = $webClient.DownloadString($scriptUri)
Invoke-Expression -Command $scriptAsString
The above example's taken from https://chocolatey.org/install

Related

What would the bat version of this powershell command be and what command would be used as the install line in sccm?

Below is the command I use in powershell to launch the app, I have deliberately used * wildcard as the app folder name changes slightly for each device. I want to replicate the wildcard in the bat file.
Start-Process -FilePath "C:\ProgramData\theapp*\theapp.exe"
therefore, for the bat file version could I use:
start "C:\ProgramData\theapp*" theapp.exe
Also, if this could be used : what install line would be best to launch this in sccm?
Massive thank you!

Add date to installer log file

I'm building an installer using advanced installer and have run into a problem trying to add dates into the log file. I tried a command using cmd which worked, however when I added it to the MSI commandline all the date values came out as blank. Below is the parameters I pass for the MSI
/L*V "C:\Log_%date:~4,2%.%date:~7,2%.%date:~10,4%-%time:~0,2%.%time:~3,2%.%time:~6,2%.log"
We are trying to make the log be Log_04.05.2019-15.03.45.log instead of Log.log since the logs get overwritten when uninstall happens or on a retry of an installation..
Advanced Installer: Sorry, I see that I must have misunderstood. You are trying to set the log file name from within Advanced
Installer. Will have a quick look. Where do you specify this command line in the tool? Please note that setting the logging policy for "Global Logging" will ensure unique log file names and that every MSI operation is logged in TMP.
Clarification: So it looks like you don't want to write to the log, but to control the file name of the log file itself?
PowerShell: I find batch files clunky with regards to stuff like this. Can you invoke the installation via Powershell? I don't really use PowerShell, but seeing as it can use .NET, maybe a simple conversion of this C# call would do the trick?
You want something like: "Log_04.05.2019-15.03.45.log", so you could perhaps try this in C#:
Console.WriteLine("Log_" + DateTime.Now.ToString("dd.MM.yyyy-HH.mm.ss") + ".log");
Here is a blog on using PowerShell with Windows Installer, see towards the bottom for this PowerShell snippet (again, I do not use PowerShell for this purpose):
$DataStamp = get-date -Format yyyyMMddTHHmmss
$logFile = '{0}-{1}.log' -f $file.fullname,$DataStamp
$MSIArguments = #(
"/i"
('"{0}"' -f $file.fullname)
"/qn"
"/norestart"
"/L*v"
$logFile
)
Start-Process "msiexec.exe" -ArgumentList $MSIArguments -Wait -NoNewWindow
Maybe also have a read about the Windows Installer PowerShell
Module (Heath Stewart) as linked to in this general purpose
answer:
How can I use powershell to run through an installer?.
Special-purpose PowerShell Module making Windows Installer operations
less clunky.
Some Links:
Various MSI logging methods: Enable installation logs for MSI installer without any command line arguments
Windows Installer Logging

%~dp0 equivalent in powershell (using Expand-Archive cmdlet)

I'm pretty new to scripting (especially powershell) and new to Stack Overflow, so please, excuse my ignorance and please bear with me! I will do my best to specifically explain what I'm looking to do and hopefully someone can give a detailed response of what I could do to make it work..
Intended Process/Work Flow: A co-worker downloads "Install.zip" file that has all the necessary files. This "Install.zip" file contains "Setup.bat" file (for computer config), "Fubar.zip" file, 2 powershell scripts, and a custom powerplan (.pow) file. Once downloaded they will run the "Setup.bat" file and it will pretty much do all the work. Inside that batch file it calls 2 powershell scripts. 1)"Download.ps1" - Downloads some other files from the web. 2.) "Unzip.ps1" - Unzips "Fubar.zip" and places contents in another folder - C:\TEST\
Issue: I've recently gotten familiar with using %~dp0 in batch files. I want to make sure that the location where my co-worker initially downloads the Install.zip doesn't throw off my batch file. So for example.. some people will download .zip files to the "Downloads" folder, then extract contents to proper destination. Others will download the .zip to a specific folder, then extract it within that folder. [Ex: C:\Alex\Install.zip --Extraction-- C:\Alex\Install\((Content))] So I tried to not pre-define file locations due to the variables. I've gotten the %~dp0 to work everywhere I need it to in my batch file. The only issue I have is getting my powershell scripts to use same working directory that my batch file is in. *My batch file and my powershell scripts will always be in the same directory. (Wherever that may be)
Goal: I want my powershell script ("Unzip.ps1") to look for my "Fubar.zip" file in the same directory that its currently running in. (Again - Wherever that may be) I basically want to remove any variables that may throw off the powershell script. I want it to always use it's current working directory to locate Fubar.zip. I basically need powershell to either use its current working directory OR figure out a way to have it pull its current working directory and use that to look for "Fubar.zip".
my current "Unzip.ps1" powershell script is extremely basic.
Unzip.ps1:Expand-Archive -Force c:\ALEX\Install.zip\Fubar.zip -dest c:\TEST\
Batch File Command that calls the Unzip.ps1 script: Powershell.exe -executionpolicy remotesigned -File %~dp0UNZIP.ps1
Please keep in mind, I'm just learning scripting and I'm teaching myself. My knowledge is limited, but I've made it this far and this is the only part I'm stuck on. Please give clear responses. Any help or advice would be extremely appreciated! Using PowerShell 5.0
Thanks in advance!
The equivalent of cmd.exe's %dp0 in PowerShell v3+ is $PSScriptRoot:
Both constructs expand to the absolute path of the folder containing the batch file / PowerShell script at hand.
(The only difference is that %dp0 contains a trailing \, unlike $PSScriptRoot).
Thus, to make your Unzip.ps1 script reference Fubar.zip in the same folder that the script itself is located in, use:
Expand-Archive -Force $PSScriptRoot\Fubar.zip -dest c:\TEST\
Constructing the path as $PSScriptRoot\Fubar.zip - i.e., blindly joining the variable value and the filename with \ - is a pragmatic shortcut for what is more properly expressed as (Join-Path $PSScriptRoot Fubar.zip). It is safe to use in this case, but see the comments for a discussion about when Join-Path should be used.
The automatic $PSScriptRoot variable requires PS v3+; in v2-, use
Expand-Archive -Force ((Split-Path $MyInvocation.Mycommand.Path) + '\Fubar.zip') -dest c:\TEST\
From your description, I gather that Fubar.zip and Unzip.ps1 are in the same directory. We'll pretend this directory is C:\Users\Me\Temp; although I understand that may vary.
Powershell's working directory will be the directory you're in (if called from CMD) when you launch; otherwise, it'll be from $env:UserProfile. Since the .bat file always call Unzip.ps1 from the directory that it's in (C:\Users\Me\Temp), powershell.exe will find it with this command (you can still use %~dp0 here; it's not hurting anything):
powershell.exe -ExecutionPolicy RemoteSigned -File Unzip.ps1
Inside of Unzip.ps1, you'll use Get-Location:
Expand-Archive -Force "$(Get-Location)\Fubar.zip" -dest c:\TEST\
However, if the .bat file does a cd into another directory, this won't work. From your %~dp0UNZIP.ps1 example, I assume this isn't the case, but let's address it anyway. If this is the case, you need to process from where the location of the script is. So for this call the full/relational path to the .ps1:
powershell.exe -ExecutionPolicy RemoteSigned -File C:\Users\Me\Temp\Unzip.ps1
Then, your Unzip.ps1 will need to look like this:
Expand-Archive -Force "${PSScriptRoot}\Fubar.zip" -dest 'C:\TEST\'
Alternatively, you can also do some fancy path splitting, as #JosefZ suggested. The $PSCommandPath and $MyInvocation variables contain the full path to your script; which you should familiarize yourself with:
$location = Split-Path $PSCommandPath -Parent
$location = Split-Path $MyInvocation.MyCommand.Path -Parent
Expand-Archive -Force "${location}\Fubar.zip" -dest 'C:\TEST\'
Note: Of course, you wouldn't set $location twice. I'm just showing you two ways to set it.
I hope this helps!
Prior to Powershell 3
$currentScriptPath = Split-Path ((Get-Variable MyInvocation -Scope 0).Value).MyCommand.Path
Otherwise, $PsScriptRoot will work. If you're going to depend on it, though, I'd make sure you mark the script with #Requires -version 3
I'd advise against changing the PWD unless you must. Which is to say, reference the variable directly.

Invoke Windows copy from PowerShell

I am busy with creating a PowerShell script where a folder needs to be copied to another folder as a part of the script.
For this I would like to use the standard Windows copy interface and leverage from the prompts and selections like “There is already a file with the same name in this location.”, “Do you want to merge this folder”, “Do this for all”, etc. instead of programming this all myself.
I investigated a view directions:
Using the IFileOperation::CopyItem method as e.g. HowTo: Display progress dialog using IFileOperation but I could find any hint of how to embed this in PowerShell
Using Verbs() Copy/Paste but although the example Invoke-FileSystemVerb -Path "C:\TestDir -Verb Cut; Invoke-FileSystemVerb -Path "\\server\share" -Verb Paste” suggests otherwise, I can paste files that are manually copied/cut but could not copy/cut files with using the CmdLet or simply using the Verb.DoIt() method (I suspect this for a security reason).
Simulate a drag-drop?
But could not find any working solution.
Any suggestion how to do this from PowerShell?
I use this to extract from ZIP files which seems to come up with all the prompts and progress bar:
$shell = New-Object -Com Shell.Application
$folder = $shell.NameSpace(“$path\Folder”)
$shell.NameSpace($otherpath).CopyHere($folder)

UnauthorizedAccessException from PowerShell when using Invoke-WebRequest

I know that the error is pretty much self-explenatory but yet I am not able to find solution. I write a PowerShell script to automate the set-up project for the dev machines. There are a set of programs that must be installed so what I want to do i first download the file and then install it. I am having problems with downloading file from the web to the local machine.
My logic is as follows. I have an .xml file where I configure all the stuff. For the downloads it looks like this:
<download source="https://github.com/msysgit/msysgit/releases/download/Git-1.9.5-preview20150319/Git-1.9.5-preview20150319.exe"
destination="C:\Temp" filename="Git-1.9.5-preview20150319.exe"/>
Then in my PowerShell script file I have this function:
function install-tools() {
Set-ExecutionPolicy RemoteSigned
$xmlFileInformation = $config.SelectNodes("/setup/downloads/download");
Foreach ($file in $xmlFileInformation)
{
$("Filename: " + $file.filename)
$("File source: " + $file.source)
$("File destionation: " + $file.destination)
$("****************************************************************");
$("*** Downlading "+ $file.filename);
$("****************************************************************");
Invoke-WebRequest $file.source -OutFile $file.destination
}
$("Task finished");
}
After executin I get the error from the title UnauthorizedAccessException from PowerShell when using Invoke-WebRequest. Two things that I can mention is that I have included Set-ExecutionPolicy RemoteSigned and also, I execute the script running PowerShell as administrator. I've tried different paths but it's the same everytime, I don't get permission to write anywhere. The only thing that I can't try is using another drive I have only one - C:\.
And one strange thing - my destination directory is C:\Temp but during one of my attempts I didn't have such a directory in C:\ so I ended up with file named Temp in my C:\ but this was the closest I get to getting a file.
I don't need to save those files in a particular place since it's very possible to delete the entire directory after successfull set-up so what I need is a way to let powershell save files somewhere in my C:\ drive. Since I'm not sure if this is related with administrating my system and setting the correct rights (I tried to lower the protection as much as I can) or I miss something in my PowerShell script?
You does not specify file name to download to. Replace
-OutFile $file.destination
to
-OutFile (Join-Path $file.destination $file.filename)

Resources