I'm currently working on a powershell script that should be able to download an attached excel file from a service now ticket, before I explain more please see the basic flow of the automation below.
The user will be asked to enter the ticket number.
The system will then find that incident ticket to accurately get the excel file needed(I saw online that I need to use sys_id).
It will then be downloaded to a specific path on the user's machine. ex: "C:\downloads\Demo\".
Following all this, I found a sample script online that I'm trying to configure to match my needs; however, I'm not sure where to get the values on that sample script. You can check the bullets below the script for the questions I have in mind.
$IncidentNumber = Read-Host -Prompt 'Enter Incident Request #'
#$admin = "admin"
#$password = "admin" | ConvertTo-SecureString -AsPlainText -Force
#$Credential = New-Object pscredential -ArgumentList ($admin,$password)
$Uri = "https://dev42835.service-now.com/api/now/table/incident?sysparm_query=number=$($IncidentNumber)&sysparm_fields=sys_id&sysparm_limit=1"
$IncidentResult = Invoke-RestMethod -Uri $Uri #-Method Get -Credential $Credential
if($IncidentResult.result.sys_id -ne $null) {
$IncidentAttachments = Invoke-RestMethod -Uri "https://dev42835.service-now.com/api/now/attachment?sysparm_query=table_sys_id=$($IncidentResult.result.sys_id)" #-Method Get -Credential $Credential
$IncidentAttachments.result | Select file_name , download_link
}
else{
"Incident Not Found!"
}
Do I really need the credentials to run the script? If yes, is there a way to
remove the need of the credentials?
Where can I get the URL that is assigned to the $URI variable?
I'm new to powershell automation so I would appreciate it if you can recommend better approach if there are any.
Yes, you need credentials but don't hard code them like that. Instead you can use built-in method Get-Credential that will securely collect your username and password. The user will have to enter their own ServiceNow credentials each time this is run.
My version only has one thing you need to configure, the $SubDomain variable which is specific to your tenant.
$SubDomain = "YourServiceNowSubdomaingoeshere" # Configure this per tenant
$Credential = Get-Credential
If(!$Credential){
# User Cancelled
exit 1
}
$IncidentNumber = Read-Host -Prompt 'Enter Incident Request #'
$Uri = "https://$SubDomain.service-now.com/api/now/table/incident?sysparm_query=number=$($IncidentNumber)&sysparm_fields=sys_id&sysparm_limit=1"
$IncidentResult = Invoke-RestMethod -Uri $Uri -Method Get -Credential $Credential
if($IncidentResult.result.sys_id -ne $null) {
$IncidentAttachments = Invoke-RestMethod -Uri "https://$SubDomain.service-now.com/api/now/attachment?sysparm_query=table_sys_id=$($IncidentResult.result.sys_id)" -Method Get -Credential $Credential
$IncidentAttachments.result | Select file_name , download_link
}
else{
"Incident Not Found!"
}
Yes you need credentials.
Your URI is the URL of your servicenow instance. Change the dev42835 portion to match. If you're unsure of your instance, contact servicenow support.
https://dev42835.service-now.com
If you use the REST API explorer, you can view API endpoints and versions which will help with forming your requests. You do need to have the rest_api_explorer role to access the REST API Explorer. If you do not have this role, contact your service-now admin requesting it.
https://docs.servicenow.com/bundle/geneva-servicenow-platform/page/integrate/inbound_rest/task/t_GetStartedAccessExplorer.html
Related
My Goal:
Use AddStringAttachment() to send a auto-generated base64 string as a .pdf file to another email address.
Coding Environment:
I'm working on WordPress with a ajax call passing a base64 string to the server. The size of the string is usually around 30kbs, it can be guaranteed not exceeding over 50kbs. I have MAX_EXECUTION_TIME 120s.
What I've Been Working Through:
I succeeded:
Sending plain text body
Sending a small .txt file
I failed:
Sending base64 string using AddStringAttachment(). The server returns me a 504 Gateway Time-out error most of time, even if $mail->send() function passes through, I can only receive a corrupt .pdf file with 10kbs bigger than original size.
Sending a already exist .pdf file with AddAttachment(), The server also returns me a 504 Gateway Time-out error, and I also get a warning like Resource interpreted as Document but transferred with MIME type application/pdf
My Code:
function sendPdf() {
$mail = new PHPMailer(true);
//Server settings
$mail->SMTPDebug = 2; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.hostinger.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'janice#popper.ga'; // SMTP username
$mail->Password = 'secret'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 587; // TCP port to connect to
//Recipient
$mail->SetFrom('janice#popper.ga');
$mail->AddAddress( 'xxxxxxxx#gmail.com' );
$pdf_base64 = $_POST[pdfString];
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject= ' New Application Form ';
$mail->Body= ' New Application Form From WordPress site ';
//Attachment
//$mail->AddStringAttachment($pdf_base64, $_POST[clientName].'_Application.pdf', 'base64', 'application/pdf');
//$mail->AddAttachment(dirname(__FILE__)."/Qian_Zhong_Application.pdf", 'Qian_Zhong_Application.pdf');
$error = '';
if(!$mail->send()){
$error = 'Mail error: '.$mail->ErrorInfo;
echo $error;
}else{
echo 'Message has been sent.';
}
exit; // This is required to end AJAX requests properly.
}
The data you pass in to addStringAttachment should be raw binary, not encoded in any way, as PHPMailer will take care of that for you. It will also set the encoding and MIME type from the filename you provide, so you do not need to set them manually.
Using a debugger would allow you to watch the script as it runs so you would be able to see exactly what it’s having trouble with. Any error 500s will cause errors to be logged in your web server logs and will usually provide more info.
I would also recommend against using $_POST[clientName] like that without any filtering or validation - you should never trust user input like that.
If I created builds from Bitrise, I can launch builds via ps1.
for example:
$postParams = '{"hook_info":{"type":"bitrise","api_token":"AQKgU--wYxRIqpZqAkIJ1A"},"build_params":{"branch":"develop"}}' $result = Invoke-WebRequest -Uri https://www.bitrise.io/app/32363315d0fd1/build/start.json -Method POST -Body $postParams
How implement it for App Center? Thx.
The following powershell syntax can be used to create new builds in App Center, just replace the variables with your own. The url of your app will contain the user and app variables. You can create an api token in your account settings.
$branch = 'master'
$user = 'exampleUser'
$app = 'exampleApp'
$token = '1234567a7c13234567c9f512346'
Invoke-WebRequest -Uri "https://api.appcenter.ms/v0.1/apps/$($user)/$($app)/branches/$($branch)/builds" -Method "POST" -Headers #{"Accept"="application/json"; "X-API-Token"="$($token)"; "Content-Type"="application/json"};
When I export binding for Dynamic Send Port Then no handler name is shown in the binding file. So is there any alternate method for that.
One suggestion by Stephen F March was to use a PowerShell script to set these.
From How to configure Send Handler for BizTalk 2013 Dynamic Send Port on deployment?
param
(
[string] $bizTalkDbServer = ".",
[string] $bizTalkDbName = "BizTalkMgmtDb",
[string] $fileHostInstance = "SendingHost",
[string] $sendPortName = "sm_dynamic_sp_test"
)
[System.reflection.Assembly]::LoadWithPartialName("Microsoft.BizTalk.ExplorerOM") | Out-Null
$catalog = New-Object Microsoft.BizTalk.ExplorerOM.BtsCatalogExplorer
$catalog.ConnectionString = "SERVER=$bizTalkDbServer;DATABASE=$bizTalkDbName;Integrated Security=SSPI"
foreach($sp in $catalog.SendPorts)
{
if($sp.Name -eq $sendPortName)
{
"Found send port $($sp.Name), analyzing send handler"
foreach($sh in $sp.DynamicSendHandlers)
{
if($sh.SendHandler.TransportType.Name -eq "FILE")
{
if($sh.SendHandler.Host.Name -ne $fileHostInstance)
{
"Changing $($sh.Name) send handler to '$fileHostInstance' from '$($sh.SendHandler.Host.Name)'"
$sp.SetSendHandler("FILE", $fileHostInstance)
}
else
{
"Send handler for $($sp.Name) is already '$fileHostInstance' ignorning .. "
}
}
}
}
}
$catalog.SaveChanges()
Sandro Pereira also just posted a blog about it called BizTalk DevOps: How to configure Default Dynamic Send Port Handlers with PowerShell
BizTalk 2013 no out of Box you need to use powershell as listed above.
For BizTalk 2016 + CU8 ( and above only) u will be able to get the Host details in the Binding File when u export .
For BizTalk 2020 use CU2 , CU1 has an issue with this
I have searched for something similar and I keep running across the FTP download answers. This is helpful information, but ultimately proving to be difficult to translate. I have found a powershell script and it works, but I am wondering if it can be tweaked for my needs. I don't have much experience with powershell scripting, but I'm trying to learn.
The need is this. I need to download and install a series of files to a remote machine, unattended. The files are distributed via email via tinyurls. I currently throw those into a .txt file, then have a powershell script read the list and download each file.
Requirements of the project and why I have turned to powershell (and not other utilities), is that these are very specialized machines. The only tools available are ones that are baked into Windows 7 embedded.
The difficulties I run into are:
The files download one at the time. I would like to grab as many downloads at the same time that the web server will allow. (usually 6)
The current script creates file names based off the tinyurl. I need the actual file name from the webserver.
Thanks in advance for any suggestions.
Below is the script I’m currently using.
# Copyright (C) 2011 by David Wright (davidwright#digitalwindfire.com)
# All Rights Reserved.
# Redistribution and use in source and binary forms, with or without
# modification or permission, are permitted.
# Additional information available at http://www.digitalwindfire.com.
$folder = "d:\downloads\"
$userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"
$web = New-Object System.Net.WebClient
$web.Headers.Add("user-agent", $userAgent)
Get-Content "d:\downloads\files.txt" |
Foreach-Object {
"Downloading " + $_
try {
$target = join-path $folder ([io.path]::getfilename($_))
$web.DownloadFile($_, $target)
} catch {
$_.Exception.Message
}
}
If you do the web request before you decide on file name you should be able to get the expanded path (otherwise you would have to make two web requests, one to get the extended path and one to download the file).
When I tried this, I found that the BaseResponse property of the Microsoft.PowerShell.Commands.HtmlWebResponseObject returned by the Invoke-WebRequest cmdlet had a ResponseUri property which was the extended path we are looking for.
If you get the correct response, just save the file using the name from the extended path, something like the following (this sample code does not look at HTTP response codes or similar, but expects everything to go well):
function Save-TinyUrlFile
{
PARAM (
$TinyUrl,
$DestinationFolder
)
$response = Invoke-WebRequest -Uri $TinyUrl
$filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString)
$filepath = [System.IO.Path]::Combine($DestinationFolder, $filename)
try
{
$filestream = [System.IO.File]::Create($filepath)
$response.RawContentStream.WriteTo($filestream)
$filestream.Close()
}
finally
{
if ($filestream)
{
$filestream.Dispose();
}
}
}
This method could be called using something like the following, given that the $HOME\Documents\Temp folder exists:
Save-TinyUrlFile -TinyUrl http://tinyurl.com/ojt3lgz -DestinationFolder $HOME\Documents\Temp
On my computer, that saves a file called robots.txt, taken from a github repository, to my computer.
If you want to download many files at the same time, you could let PowerShell make this happen for you. Either use PowerShell workflows parallel functionality or simply start a Job for each url. Here's a sample on how you could do it using PowerShell Jobs:
Get-Content files.txt | Foreach {
Start-Job {
function Save-TinyUrlFile
{
PARAM (
$TinyUrl,
$DestinationFolder
)
$response = Invoke-WebRequest -Uri $TinyUrl
$filename = [System.IO.Path]::GetFileName($response.BaseResponse.ResponseUri.OriginalString)
$filepath = [System.IO.Path]::Combine($DestinationFolder, $filename)
try
{
$filestream = [System.IO.File]::Create($filepath)
$response.RawContentStream.WriteTo($filestream)
$filestream.Close()
}
finally
{
if ($filestream)
{
$filestream.Dispose();
}
}
}
Save-TinyUrlFile -TinyUrl $args[0] -DestinationFolder $args[1]
} -ArgumentList $_, "$HOME\documents\temp"
}
Problem
Our web host provider is changing the IP address of one of the servers we are on. We have been given a time frame for when the switch will take place, but no exact details. Therefore, our current poor man's check requires a periodic page refresh on a browser to see if our website is still there.
Question
We are all programmers here and this is killing me that any manual checking is required. I would know how to do this in other languages, but want to know if there is a way to write a script in PowerShell to tackle this problem. Does anyone know how I might going about this?
If you can alert if the page is gone or does not have an expected value, you could use a script like
$ip = 192.168.1.1
$webclient = new-object System.Net.WebClient
$regex = 'regular expression to match something on your page'
$ping = new-object System.Net.NetworkInformation.Ping
do
{
$result = $ping.Send($ip)
if ($result.status -ne 'TimedOut' )
{
$page = $webclient.downloadstring("http://$ip")
if (($page -notmatch $regex) -or ($page -match '404') -or ($page -eq $null))
{ break}
}
} while ($true)
write-host "The website has moved"
This will list the IP Address for each network adapter in your system.
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName . | Select-Object -Property IPAddress