Have this question: how I can do REST calls to Sharepoint 2013/2016 REST api, from another host, lets say, another server, but within the same domain.
By default, CORS policy will deny any request that does not come from the same host.
I am trying to retrieve some information doing an AJAX REST request from another host.
Thanks!!
Enable SharePoint configure to enable cross domain access.
Below script is shared by Ingo Karstein here
Add-PSSnapin Microsoft.SharePoint.PowerShell -EA 0
$localFarm = Get-SPFarm
$webapp = Get-SPWebApplication "http://sp:12001"
# Remove old web.config modifications of MyAuthenticationProvider
$oldMods = #();
$webapp.WebConfigModifications | ? { $_.Owner -eq "CrossSiteScripting" } | % {
$oldMods = $oldMods + $_
}
$oldMods | % {
$webapp.WebConfigModifications.Remove($_)
}
# update the Web Application and apply all existing web.config modifications - this executes the "remove" actions from above
$webapp.Update()
[Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplyWebConfigModifications()
#Wait until web.config modifications finished by timer job
while( (Get-SPTimerJob | ? { $_.Name -eq "job-webconfig-modification"}) -ne $null ) {
Write-Host "." -NoNewline
Start-Sleep 1
}
# New web.config modifications for MyAuthenticationProvider
$myModification1 = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$myModification1.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$myModification1.Name = "add[#name='Access-Control-Allow-Origin'][#value='http://wfm:13002']"
$myModification1.Sequence = 0
$myModification1.Owner = "CrossSiteScripting"
#0 = for the enum value "SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode"
$myModification1.Type = 0
$myModification1.Value = "<add name='Access-Control-Allow-Origin' value='http://wfm:13002' />"
$webapp.WebConfigModifications.Add($myModification1)
$myModification1 = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$myModification1.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$myModification1.Name = "add[#name='Access-Control-Request-Method'][#value='GET,POST,HEAD,OPTIONS']"
$myModification1.Sequence = 0
$myModification1.Owner = "CrossSiteScripting"
$myModification1.Type = 0
$myModification1.Value = "<add name='Access-Control-Request-Method' value='GET,POST,HEAD,OPTIONS' />"
$webapp.WebConfigModifications.Add($myModification1)
$myModification1 = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$myModification1.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$myModification1.Name = "add[#name='Access-Control-Request-Headers'][#value='Content-Type,Authorization']"
$myModification1.Sequence = 0
$myModification1.Owner = "CrossSiteScripting"
$myModification1.Type = 0
$myModification1.Value = "<add name='Access-Control-Request-Headers' value='Content-Type,Authorization' />"
$webapp.WebConfigModifications.Add($myModification1)
$myModification1 = new-object Microsoft.SharePoint.Administration.SPWebConfigModification
$myModification1.Path = "configuration/system.webServer/httpProtocol/customHeaders"
$myModification1.Name = "add[#name='Access-Control-Allow-Credentials'][#value='true']"
$myModification1.Sequence = 0
$myModification1.Owner = "CrossSiteScripting"
$myModification1.Type = 0
$myModification1.Value = "<add name='Access-Control-Allow-Credentials' value='true' />"
$webapp.WebConfigModifications.Add($myModification1)
$webapp.Update()
[Microsoft.SharePoint.Administration.SPWebService]::ContentService.ApplyWebConfigModifications()
#Wait until web.config modifications finished by timer job
while( (Get-SPTimerJob | ? { $_.Name -eq "job-webconfig-modification"}) -ne $null ) {
Write-Host "." -NoNewline
Start-Sleep 1
}
My test result:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<input id="Button1" type="button" onclick="getListItems()" value="button" />
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script type="text/javascript">
function getListItems() {
var dataEndPoint = "http://sp:12001/_api/web/lists/getbytitle('Versions')/items";
$.ajax({
url: dataEndPoint,
type: "GET",
headers: {
"Accept": "application/json;odata=verbose"
},
crossDomain: true,
xhrFields: { withCredentials: true },
success: function (data) {
alert(data.d.results.length);
},
error: function (response) {
alert("Error");
}
})
}
</script>
</body>
</html>
Related
I have created this script:
Function Make-Base64Image
{
<#
.NOTES
=============================================================================================================================================
Created with: Windows PowerShell ISE
Created on: 28-Oct-2022
Created by: TheStingPilot
Organization:
Functionname: Make-Base64Image
=============================================================================================================================================
.SYNOPSIS
This function removes the given bit from the picture.
Based on:
https://devblogs.microsoft.com/scripting/expert-solution-for-2011-scripting-games-advanced-event-8-use-powershell-to-resize-images-and-to-remove-exif-data/
#>
Param
(
[Parameter(Mandatory=$True)] [System.IO.FileInfo] $SourceFileName,
[Parameter(Mandatory=$False)][Int] $Scale = 100
)
$img = [System.Drawing.Image]::FromFile($SourceFileName)
$ImgFormat = [System.Drawing.Imaging.ImageFormat]::Jpeg
$Size = "$([int]($img.Width*($Scale/100))), $([int]($img.Height*($Scale/100)))"
$img_new = New-Object System.Drawing.Bitmap($img, $Size)
$MemoryStream = New-Object -TypeName System.IO.MemoryStream
$img_new.Save($MemoryStream, $ImgFormat)
$cImgBytes = [Byte[]]($MemoryStream.ToArray())
$sBase64 = [System.Convert]::ToBase64String($cImgBytes)
Return $sBase64
}
$CurrentDir = $(Split-Path $MyInvocation.MyCommand.Definition)
$Picture = "$CurrentDir\WP_20170426_15_19_09_Pro.jpg"
$sBase64 = Make-Base64Image -SourceFileName $Picture -Scale 20
$CSS = #"
<style type="text/css">
.image-wrapper img {
object-fit: contain;
object-position: bottom;
height: 806px;
width: 806px;
}
</style>
"#
$HTML = #"
<html>
<head>
{0}
<title>Test</title>
</head>
<body>
<h1>Test</h1>
<p>Hello World</p>
<div class="image-wrapper"><img alt="Embedded Image" src="data:image/jpeg;base64,{1}" style="transform:rotate(90deg);"></img></div>
</body>
</html>
"#
$HTMLDocument = $HTML -f $CSS, $sBase64
$HTMLOutput = "$CurrentDir\testfile.html"
$HTMLDocument | Out-File -FilePath $HTMLOutput -Force
$DLLFiles = (Get-ChildItem -Path "$CurrentDir\DLLFilesForItext7" -Filter *.dll -File).FullName
ForEach ($DLLFile in $DLLFiles)
{
Add-Type -Path $($DLLFile)
}
$PDFFileToWrite = [System.IO.FileInfo]::new($HTMLOutput.Replace(".html",".pdf"))
$HTMLInputFile = [System.IO.FileInfo]::new($HTMLOutput)
[iText.Html2Pdf.HtmlConverter]::ConvertToPdf($HTMLInputFile,$PDFFileToWrite)
What I see is that the created PDF has the picture not on the left side. If I do not apply the object-position in the CSS the same result can be seen in the created html file. To me, it seems that iText7 does not apply the object-position.
Is there an alternative for this?
What can I do to resolve this issue?
The code plus picture can be found here.
Feedback is appreciated.
With kind regards,
TheStingPilot
I copied and pasted this code https://community.idera.com/database-tools/powershell/powertips/b/tips/posts/creating-powershell-web-server in a powershell console directory which contains an index.html file
when browsing to http://localhost:8080/index.html I get an error Oops, the page is not available!
Is there something wrong with the code I can't see what ?
# enter this URL to reach PowerShell’s web server
$url = 'http://localhost:8080/'
# HTML content for some URLs entered by the user
$htmlcontents = #{
'GET /' = '<html><building>Here is PowerShell</building></html>'
'GET /services' = Get-Service | ConvertTo-Html
}
# start web server
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add($url)
$listener.Start()
try
{
while ($listener.IsListening) {
# process received request
$context = $listener.GetContext()
$Request = $context.Request
$Response = $context.Response
$received = '{0} {1}' -f $Request.httpmethod, $Request.url.localpath
# is there HTML content for this URL?
$html = $htmlcontents[$received]
if ($html -eq $null) {
$Response.statuscode = 404
$html = 'Oops, the page is not available!'
}
# return the HTML to the caller
$buffer = [Text.Encoding]::UTF8.GetBytes($html)
$Response.ContentLength64 = $buffer.length
$Response.OutputStream.Write($buffer, 0, $buffer.length)
$Response.Close()
}
}
finally
{
$listener.Stop()
}
It does work if you go to just http://localhost:8080/, you'd have to also have an index.html listing in order to browse to that too.
Just modify the $htmlContents section like so:
# HTML content for some URLs entered by the user
$htmlcontents = #{
'GET /' = '<html><building>Here is PowerShell</building></html>'
'GET /services' = Get-Service | ConvertTo-Html
'GET /index.html' = '<html><building>this is my index page</building></html>'
}
You could also have a statement like this.
$htmlcontents = #{
'GET /' = '<html><building>Here is PowerShell</building></html>'
'GET /services' = Get-Service | ConvertTo-Html
'GET /index.html' = '<html><building>this is my index page</building></html>'
'GET /fromPage.html' = Get-content "C:\temp\fence.txt"
}
I have the following problem:
I use a PS script that scrapts a web page. Based on the response, it concludes if the site is up or down.
My code works
foreach ($site in $websitesArray) {
$Counter = 5
$ErrorCounter = 0
if ($site -like 'http://*') {
$siteSplit = $site.Replace("http://", "")
}
else {
$siteSplit = $site.Replace("https://", "")
}
$ip = [System.Net.Dns]::GetHostAddresses($siteSplit)
for (int i = 0 ; i -lt $Counter ; i++) {
Try {
$HTMLstring = $web.DownloadString($site)
}
Catch {
$ErrorCounter++
}
Start-Sleep 5s
}
if ($ErrorCounter > 3) {
$body += "The website " + $site + " (" + $ip + ") has returned an HTTP error and is down <br />"
}
}
The problem is that the following is returned for pages that have a Cookie Policy pop up:
The remote server returned an error: (500) Internal Server Error.
What workaround could I use to prevent this false positive from happening? Keep in mind that I have a list of websites so a hardcoded solution wouldn't be helping me.
I was successfully able to open a port on my computer (using only PowerShell) and know when HTTP requests are done to that port. I came up with this simple code:
$listener = [System.Net.Sockets.TcpListener]5566;
$listener.Start();
while ($true) {
$client = $Listener.AcceptTcpClient();
Write-Host "Connected!";
$client.Close();
}
If I open my browser and type http://localhost:5566 in the PowerShell interface it will show a message that a user got connected.
What I need to do is to get the GET parameters of this HTTP request. For example, if instead I had opened my browser and typed http://localhost:5566/test.html?parameter1=xxx¶meter2=yyy.
How can I grab the GET parameters (parameter1 and parameter2) name and values using my simplified code above?
If you are comfortable using the HttpListener instead of the TcpListener. It's easier to do the job.
Below script will output in a browser
Path is /test.html
parameter2 is equal to yyy
parameter1 is equal to xxx
Quick and dirty script
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://localhost:5566/")
try {
$listener.Start();
while ($true) {
$context = $listener.GetContext()
$request = $context.Request
# Output the request to host
Write-Host $request | fl * | Out-String
# Parse Parameters from url
$rawUrl = $request.RawUrl
$Parameters = #{}
$rawUrl = $rawUrl.Split("?")
$Path = $rawUrl[0]
$rawParameters = $rawUrl[1]
if ($rawParameters) {
$rawParameters = $rawParameters.Split("&")
foreach ($rawParameter in $rawParameters) {
$Parameter = $rawParameter.Split("=")
$Parameters.Add($Parameter[0], $Parameter[1])
}
}
# Create output string (dirty html)
$output = "<html><body><p>"
$output = $output + "Path is $Path" + "<br />"
foreach ($Parameter in $Parameters.GetEnumerator()) {
$output = $output + "$($Parameter.Name) is equal to $($Parameter.Value)" + "<br />"
}
$output = $output + "</p></body></html>"
# Send response
$statusCode = 200
$response = $context.Response
$response.StatusCode = $statusCode
$buffer = [System.Text.Encoding]::UTF8.GetBytes($output)
$response.ContentLength64 = $buffer.Length
$output = $response.OutputStream
$output.Write($buffer,0,$buffer.Length)
$output.Close()
}
} finally {
$listener.Stop()
}
Cheers
Glenn
Ok, i try add Test-Connection and now the code look likes this:
$html=
#'
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
<style type="text/css">
.alert {{
background-color: #FB1717 }}
.statusCom {{
background-color: #FB1717
}}
</style>
</head>
<body>
<table>
<colgroup><col/><col/><col/><col/><col/><col/><col/><col/></colgroup>
<tr><th>SystemName</th><th>DeviceID</th><th>VolumeName</th><th>Size(GB)</th><th>FreeSpace(GB)</th><th>Status</th></tr>
{0}
</table>
</body></html>
'#
$entryTemplate = '<tr><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>'
$alertEntryTemplate = '<tr class="alert"><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td></tr>'
$statusTemplate = '<tr class="statusCom"><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td><td>{7}</td></tr>'
Function Get-ComInfo {
param(
$computers
)
#Here LOW Space thresold is lessthan 10% of the total size of the Volume
$PercentFree = #{Name="FreeSpace(GB)";Expression={"{0:N1}" -f($_.freespace /1GB)}}
Get-WmiObject Win32_LogicalDisk -filter "DriveType=3" -computer $computers |
Select SystemName,DeviceID,VolumeName,$PercentFree,#{Name="Size(GB)";Expression={"{0:N1}" -f($_.size/1gb)}},#{name="PercentFree(%)";Expression={int}}
}
$servers = Get-Content U:\Users\xxx\Desktop\servers.txt
$client = $servers
if(Test-Connection -ComputerName (Get-Content U:\Users\xxx\Desktop\servers.txt ) -BufferSize 16 -Count 1 -Quiet) {
$entries = $servers | % { Get-ComInfo -computers $_ } | % {
if ([float]::Parse($_.'FreeSpace(GB)') -le 5) {
$alertEntryTemplate -f $_.SystemName, $_.DeviceID, $_.VolumeName, $_.'FreeSpace(GB)', $_.'Size(GB)', $_.'PercentFree(%)', $_.'LOW SPACE'
}
else {
$entryTemplate -f $_.SystemName, $_.DeviceID, $_.VolumeName, $_.'FreeSpace(GB)', $_.'Size(GB)', $_.'PercentFree(%)', $_.'LOW SPACE'
}
}
}
else{
$statusTemplate -f $_.SystemName, $_.DeviceID, $_.VolumeName, $_.'FreeSpace(GB)', $_.'Size(GB)', $_.'PercentFree(%)', $_.'LOW SPACE', $_.'Status'
}
$html -f ($entries -join ' ') | out-file U:\Users\xxx\Desktop\Drivess.html
$OutputFile = "U:\Users\xxx\Desktop\Drivess.html"
$SMTPServer = "smtp.xxx.com"
$EmailFrom = "xxxx#xxx.com"
$EmailTo = "xxxx#xxx.com"
$Subject = "$computers PROGRES ;))"
$body = (Get-Content $OutputFile)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
$SMTPClient.EnableSsl = $false
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("xxx", "xxx");
$MailTextT = Get-Content -Path U:\Users\xxx\Desktop\Drivess.html -Raw
$msg = New-object Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $body)
$msg.IsBodyHTML = $true
$SMTPClient.Send($msg)
In html i add this:
.statusCom {{
background-color: #FB1717
}}
And:
$statusTemplate = '<tr class="statusCom"><td>{0}</td><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td><td>{6}</td><td>{7}</td></tr>'
And i have more than one computer and one is offline in my servers.txt it i get this error:
Get-WmiObject : Serwer RPC it is offline. (Expectiob HRESULT: 0x800706BA)
At U:\Users\xxx\Desktop\test.ps1:36 char:1
+ Get-WmiObject Win32_LogicalDisk -filter "DriveType=3" -computer $comp ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
+ FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
If i have one computer and it is offline a get this:
<tr class="statusCom"><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>
What i do wrong?
if (Test-Connection -ComputerName COMPUTERNAME_HERE -Count 1 -EA SilentlyContinue) { "online" } else { "offline" }
You Need to take this somewhere into your script, this should be easily done.
You can use the Systemname as Computername, provided by the Get-ComInfo function and you need to extent your two templates by a {7} for online/offline information.