Call an URL with Scheduled Powershell Script - powershell

I just want to call an URL with the tasks scheduler on Windows Server 2008 and a Powershell Script.
So I developed the following script :
$url = "http://example.com"
$log_file = "${Env:USERPROFILE}\Desktop\Planification.log"
$date = get-date -UFormat "%d/%m/%Y %R"
"$date [INFO] Exécution de $url" >> $log_file
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$response.Close()
The script works without any issue when I execute it from the Powershell ISE, the Powershell console or with the command :
powershell PATH_TO_MY_SCRIPT.ps1
But it doesn't works when I execute it from the Scheduler tasks, it returns the code 0xFFFD0000. I found this : http://www.briantist.com/errors/scheduled-task-powershell-0xfffd0000/
So it can be a permission problem, so I tried many others profiles and option (including "Execute with all permissions") to test, without success.
I execute also another Powershell script which just mount a network drive and copy two files, and I don't have any issue with this script. So I think that the issue come from the using of the .NET object to call my URL.
I saw that I may have to include modules in my script before any other commands, but I don't know exactly what I have to do. (I don't know Powershell, I just try to use it for resolving my problems).
Thank you for you help.

i used the following in a scheduled task and it works as expected :
$url="http://server/uri"
(New-Object System.Net.WebClient).DownloadString("$url");

following code should do what you need.
$url = "http://www.google.com"
PowerShell Invoke-WebRequest -Uri $url -Method GET

You'll want to put that log file out somewhere in a shared directory. Scheduled tasks may or may not have access to $env:USERPROFILE. Also, use Start-Transcript to have PowerShell write your script's output to a log file (except for STDOUT, you'll need to pipe the output from executables to Write-Host, e.g. hostname | Write-Host).
$url = "http://example.com"
$log_file = "C:\PlanificationLogs\Planification.log"
Start-Transcript -Path $log_file
Get-Date -UFormat "%d/%m/%Y %R"
Write-Host "$date [INFO] Exécution de $url"
# PowerShell 3
Invoke-WebRequest -Uri $url
# PowerShell 2
$request = [System.Net.WebRequest]::Create($url)
$response = $request.GetResponse()
$response.Close()

Related

How do I add a powershell script to be run post setup during a windows 10 unattended install?

I may be going about this the wrong/more difficult way. I am open to suggestions.
I am running NTLite v2.3.8.8920 [HOME] ((c) NTlitesoft d.o.o) to create unattended Windows 10 discs. After years of doing unattended discs and realizing the ever expanding size of the disc, (Latest disc was 32.73GB!), I found WinGet, the absolutely amazing repository, and have even gone as far as to create my own installer!
The issue for today is: how do I access WinGet during an unattended installation? I have compiled a list of applications that I use frequently; most that I have been hard coding to the disc and thus this incredible size; and I would love to be able to run this script post-setup and save the time and space. Here is my code:
#The first batch here is a function I created for notification purposes. Not sure how to do timed popups in Powershell yet.
#Get Words
function GW($myinput){
$WS = New-Object -ComObject "Wscript.Shell"
$ws.popup($myinput,3,'TK Installer',64)|SET-CLIPBOARD}
SET-CLIPBOARD to offload the popup response code. Need to find a better output or a way to prevent printing this response.
function install-myapps(){
Clear-Host
#Variable to hold the application list
$myapps = (
'Microsoft.PowerShell',
'Microsoft-Windows.Terminal',
'Microsoft.DotNet.SDK.3_1',
'Microsoft.DotNet.SDK.5',
'Microsoft.DotNet.SDK.6',
'Microsoft.MSIXCore',
'Microsoft.msmpisdk',
'Microsoft.ADKPEAddon',
'Microsoft.WebDeploy',
'9N5LW3JBCXKF',
'Nlitesoft.NTLite',
'Libretro.RetroArch',
'Notepad++.Notepad++',
'CodecGuide.K-LiteCodecPack.Full',
'Foxit.FoxitReader',
'7zip.7zip',
'OBSProject.OBSStudio',
'XnSoft.XnConvert',
'XnView.Classic',
'XnSoft.XnViewMP',
'corel.winzip',
'XP8K0J757HHRDW')
#Parser
ForEach-Object($aa in $myapps.Split(',')){
#Notification
GW "Installing $aa`nPlease wait..."
#Installer
WinGet install $aa --silent --accept-package-agreements --accept-source-agreements --force}
}
This code works perfectly in both command line and exe format; the latter using PS2EXE or IExpress. I just cannot figure out how to instantiate it post-setup from the unattended Win1021H2 side. Any help or insight would be greatly appreciated!
I was unable to figure out the process for this so I worked it around differently.
Below is how I fixed this situation:
# The first section opens and names function and
# declares variable $Hopeful applied to the full URI for the application we are installing
# !Considering using get-input but for now we will just use a replaceable variable!
# The second section begins the downloading and saving process
# Begins by separating the application from the URI assuming the format is as www.domain.com/application.exe
# Note now that the variable $JustApp will pull the just the last portion of the URI which is the application name
# Also, we'll make sure that what we're trying to do is possible by checking the extension of the last object
# Because wget needs 2 things; the URI and a place for the download to go; I am creating a directory to put these
# downloads in. Thus, $MyDir\$JustApp is now the default file point.
cls
Clear-Host
$MyDir = "d:\TKDI\"
# Create directory
if($mydir|Test-Path){
"My Directory Already Exists!"
}else{
md $MyDir -Force
}
# Section 1
Function TKDI($Hopeful,$MyArgs){
$_|select
# Section 2
$JustApp = $hopeful -split('/')|select -last 1
if($justapp -match "exe")
{
switch($MyArgs)
{
inno{$x ='/sp- /silent /forcecloseapplications /restartapplications /norestart'}
S{$x ='/S'}
silent{$x ='/silent'}
quiet{$x ='/quiet'}
passive{$x ='-passive'}
default{$x =$myargs}
un{$x ='-uninstall'}
$null{$x='/?'}
}
cls
echo "Processing $justapp"
if(Test-Path $mydir$justapp -PathType Leaf){echo 'File Downloaded Already!'}else{wget -Uri $hopeful -OutFile $MyDir$justapp}
$noteit = 'Installing $justapp in 5 seconds...'
$x=6;while($x-- -ge 1){cls;Write-host $x;sleep 1}
start -verb runas -wait -FilePath $mydir$justapp -ArgumentList $x
}elseif($justapp -match "msi")
{
cls
echo "You're file will be downloaded and installed!"
wget -Uri $hopeful -OutFile $MyDir$justapp
start -wait -Verb runas msiexec.exe -ArgumentList "-i $mydir$justapp /passive /norestart"
}else{
echo "This URI does not result in an application!"
}
}
tkdi www.example.com/index.exe inno #Installs beautifully```

Powershell, Invoke Web-Request Error (just at Windows Server 2012R)

at the moment i am writing some scripts to handle our Backups of our Costumers.
So the backups are running over a Synology Box.
The Script works really fine with Windows 10 and Windows Server 2019.
But i can not start it at WindowsServer 2012R2. And i tried so many things to handle but it didnt work.
$ip = "XXXXXXXXXX"
$u = "XXXXXXX"
$p = "XXXXXXX"
$d = "XXXXXX"
#Session ID auslesen & Authentifizierung
$a = Invoke-WebRequest -UseBasicParsing "http://$ip/webapi/auth.cgi?api=SYNO.API.Auth&version=2&method=login&account=$u&passwd=$p&session=ActiveBackup&format=cookie"
$ajson = $a.Content
$aobject = ConvertFrom-Json -InputObject $ajson
$s = $aobject.data.sid
At first he shows me the error that he can not handle utf-8, ive updated Powershell to Version 5.1 and now Windows always tells me that the Value of $a is not allowed to be null. It Seems that he cannot receive any session Number. On Windows 10 and Windows Server 2019 it runs perfectly. Please can anybody help me please. Would beeee really nice
Greetings
Yaspo
Edit i got it.
For everybody who got the same problems just go the classic way without
invoke-webrequest
$url = "http://$ip/webapi/auth.cgi?api=SYNO.API.Auth&version=2&method=login&account=$u&passwd=$p&session=ActiveBackup&format=cookie"
$wc = New-Object System.Net.WebClient
$result = $wc.DownloadString($url)

What is the curl equivalent command in powershell for uploading the apk file?

I am trying to perform CI/CD using Perfecto and hence I am trying to upload a file to perfecto when my Bamboo build is finished.
I was trying with the following cURL command when we have a Linux server.
curl -X POST --upload-file test.apk 'https://****.perfectomobile.com/services/repositories/media/PRIVATE:test.apk?operation=upload&user=<email>&password=<password>&overwrite=true'
Now our server is changed to Windows and hence I want a powershell script which I can use as an Inline Scripts in Bamboo.
Can you please tell me what is an equivalent script in Powershell for windows.
Many thanks in advance.
# Gather your information.
$email = "myEmail#website.com";
$password = "powershellR0cks!";
$subDomain = "****";
$url = "https://$subDomain.perfectomobile.com/services/repositories/media/PRIVATE:test.apk?operation=upload&user=$email&password=$password&overwrite=true";
$filePath = ".\test.apk";
# Make the request.
$response = Invoke-WebRequest -Uri $URL -Method Post -InFile $filePath -ContentType "application/octet-stream";
# Check for success.
if (-not ($response.StatusCode -eq 200)) {
throw "There was an error uploading the APK manifest.";
}
You may want to check the value of -ContentType, but I think that's correct. You don't necessarily need to include the scheme (HTTPS) if you don't want to, and semicolons in PowerShell are optional, but you can include them if you want.
The $response variable is an HtmlWebResponseObject that has the content of the response, the status code, and a bunch of other useful info. You can check out the available properties and methods on the object by running $response | Get-Member.
Finally, the Invoke-WebRequest cmdlet also has other parameters that may be useful to you, such as -Credential, -Headers, and more.
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1
As a side-note, if you run Get-Alias -Name "curl", you can see that anytime you use curl in PowerShell, you're really just calling Invoke-WebRequest. You can use the curl alias if you want, but it's generally not a good idea to use aliases in automation since they can be modified or deleted.

Invoke-RestMethod OutFile Empty When PassThru Used

Using PowerShell 4.0 and Invoke-RestMethod cmdlet. I'm having trouble with the -OutFile and -PassThru options. Whenever I add the -PassThru option, my -OutFile is created but the contents are Empty!
According to the Invoke-RestMethod Documentation, both an output file and pipeline object should be available when these options are used together. "-OutFile Saves the response body in the specified output file. [...] To send the results to a file and to the pipeline, use the Passthru parameter."
Here's a test to repeat the problem I'm having. Here I'm calling a rest api attempting to BOTH save response to file AND deserialize into a powershell object.
"POWERSHELL VERSION $($host.Version.ToString())"
$date = Invoke-RestMethod "http://date.jsontest.com" -OutFile "OutFile.txt" -PassThru
Get-Content "OutFile.txt"
# FILE IS EMPTY!!! PASSTHRU SEEMS TO RESULT IN EMPTY FILE
$date
# powershell object has the date received from api
Here are two tests to verify the normal functionality of Invoke-RestMethod WITHOUT the PassThru option
# ... Test # 1, call rest api and deserialize into powershell object
$date = Invoke-RestMethod "http://date.jsontest.com"
$date
# Output shows the date retrieved from sample restful service
# ... Test # 2, call rest api and save response body directly to a file
Invoke-RestMethod "http://date.jsontest.com" -OutFile "OutFile.txt"
Get-Content "OutFile.txt"
# Output shows contents of rest api response body (json text)
I think these tests should help others see the trouble I'm having. My question is whether there is something I'm missing to make this work, or whether this may be a bug with the cmdlet? I've Googled a bit for solution and no obvious reports of this issue. I'm wanting to use -OutFile as part of a workaround for another Invoke-RestMethod issue related to content encoding as described at Bug? Invoke-RestMethod and UTF-8 data. The -PassThru option is helpful for me to look at the returned data and terminate iteration on a multi-request (paged) odata result set.
I believe the -PassThru switch redirects all output to the console only, and I think that is why your file is empty. However, since you have it a variable you could add one more line like so. . .
Write-Output -InputObject $date | Out-File -FilePath "OutFile.txt"

Download URL content using PowerShell

I am working in a script, where I am able to browse the web content or the 'url' but I am not able to copy the web content in it & download as a file.
This is what I have made so far:
$url = "http://sp-fin/sites/arindam-sites/_layouts/xlviewer.aspx?listguid={05DA1D91-F934-4419-8AEF-B297DB81A31D}&itemid=4&DefaultItemOpen=1"
$ie=new-object -com internetexplorer.application
$ie.visible=$true
$ie.navigate($url)
while($ie.busy) {start-sleep 1}
How can I copy the content of $url and save it to local drive as a file?
Update:
I got these errors:
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (401) Unauthorized." At :line:6 char:47 + (New-Object system.net.webclient).DownloadFile( <<<< "$url/download-url-content", 'save.html' )
Missing ')' in method call. At :line:6 char:68 + (New-Object system.net.webclient).DownloadFile( "$url", 'save.html' <<<<
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (401) Unauthorized." At :line:6 char:47 + (New-Object system.net.webclient).DownloadFile( <<<< "$url", 'save.html' )
Ok, let me explain more, on what I am trying to do: I have a excel file in our share point site & this is the file I am trying to download locally(any format), which is a part of the script, so that for the later part of the script, I can compare this file with other data & get an output.
Now if I can somehow map "my documents" from the site & able to download the file, that will also work for me.
Update Jan 2014: With Powershell v3, released with Windows 8, you can do this:
(Invoke-webrequest -URI "http://www.kernel.org").Content
Original Post, valid for Powershell Version 2
This solution is very similar to the other answers from stej, Jay Bazusi and Marco Shaw.
It is a bit more general, by installing a new module into your module directory, psurl. The module psurl adds new commands in case you have to do a lot of html-fetching (and POSTing) with powershell.
(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
See the homepage of the code-sharing website http://psget.net/.
This nice line of PowerShell script will dowload GetPsGet.ps1 and send
it to Invoke-Expression to install PsGet Module.
Then install PsUrl, a Powershell Module inspired by curl:
To install something (in our case PsUrl) from central directory just type:
install-module PsUrl
get-module -name psurl
Output:
ModuleType Name ExportedCommands
---------- ---- ----------------
Script psurl {Get-Url, Send-WebContent, Write-Url, Get-WebContent}
Command:
get-command -module psurl
Output:
CommandType Name Definition
----------- ---- ----------
Function Get-Url ...
Function Get-WebContent ...
Alias gwc Get-WebContent
Function Send-WebContent ...
Alias swc Send-WebContent
Function Write-Url ...
You need to do this only once.
Note that this error might occur:
Q: Error "File xxx cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details."
A: By default, PowerShell restricts execution of all scripts. This is all about security. To "fix" this run PowerShell as Administrator and call
Set-ExecutionPolicy RemoteSigned
From now on, in your new powershell sessions/scripts, do this:
import-module psurl
get-url "http://www.google.com"
To download and save to a file, do this:
get-url "http://www.google.com" | out-file -filepath "myfile.html"
As I understand it, you try to use IE because if automatically sends your credentials (or maybe you didn't know of any other option).
Why the above answers don't work is because you try to download file from SharePoint and you send an unauthenticated request. The response is 401.
This works:
PS>$wc=new-object system.net.webclient
PS>$wc.UseDefaultCredentials = $true
PS>$wc.downloadfile("your_url","your_file")
if the the current user of Posh has rights to download the file (is the same as the logged one in IE).
If not, try this:
PS>$wc=new-object system.net.webclient
PS>$wc.Credentials = Get-Credential
PS>$wc.downloadfile("your_url","your_file")
If you just want to download web content, use
(New-Object System.Net.WebClient).DownloadFile( 'download url content', 'save.html' )
I'm not aware of any way to save using that interface.
Does this render the page properly:
PS>$wc=new-object system.net.webclient
PS>$wc.downloadfile("your_url","your_file")
As already answered in https://stackoverflow.com/a/35202299/4636579, but with a mandatory Proxy and the credentials. Without proxy, it would be:
$url="http://aaa.bbb.ccc.ddd/rss.xml"
$WebClient = New-Object net.webclient
$path="C:\Users\hugo\xml\test.xml"
$WebClient.DownloadFile($url, $path)
$web = New-Object Net.WebClient
$web | Get-Member
$content=$web.DownloadString("http://www.bing.com")
If you're truly only concerned with the raw string content, the best route, as mentioned by a few others, is using the constructs within .NET to do this. However, I think in the previous answers a few opportunities are missed.
It's often best to use WebRequest over WebClient as it provides better control over the entire request cycle
Response buffering via System.IO.StreamReader, made possible by using WebRequest
Creating a testable, reusable tool. Which is the very nature and purpose of PowerShell
function Get-UrlContent {
<#
.SYNOPSIS
High performance url fetch
.DESCRIPTION
Given a url, will return raw content as string.
Uses:
System.Net.HttpRequest
System.IO.Stream
System.IO.StreamReader
.PARAMETER Url
Defines the url to download
.OUTPUTS
System.String
.EXAMPLE
PS C:\> Get-UrlContent "https://www.google.com"
"<!doctype html>..."
#>
[cmdletbinding()]
[OutputType([String])]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[string] $Url)
Write-Debug "`n----- [Get-UrlContent]`n$url`n------`n`n"
$req = [System.Net.WebRequest]::CreateHttp($url)
try {
$resp = $req.GetResponse()
}
catch {
Write-Debug "`n------ [Get-UrlContent]`nDownload failed: $url`n------`n"
}
finally {
if ($resp) {
$st = $resp.GetResponseStream()
$rd = [System.IO.StreamReader]$st
$rd.ReadToEnd()
}
if ($rd) { $rd.Close() }
if ($st) { $st.Close() }
if ($resp) { $resp.Close() }
}
}