Http Request or cURL in Windows 10 - cephadm

How to request HTTP in Windows 10 by default without installing any plugin?
curl -X POST http://you-url.com/api/search

We can use the PowerShell
$Uri = 'http://you-url.com/api/search'
$Fields = #{
properties='{"color": "red"}'
maxitems='30'
skipcount='0'
location='country'
userName='testing'
password='testing'
}
Invoke-RestMethod -Uri $Uri -Method Post -Body $Fields | ConvertTo-Json -Depth 10;

Related

Business Central Admin API - can't delete/stop sessions

Using powershell, I can connect to the business central admin API with a registered app on Azure as per the following setup Business Central Admin API. I am able to retrieve the list of environments and also the list of sessions etc. One of the key requirements when using the API, is to be able to delete/stop sessions. However when I attempt to do this, it is giving me an error which is basically a null response for the delete method.
# This sample authenticates to Azure Active Directory (AAD) an obtains an access token.
# The access token can be used for authenticating to Business Central APIs.
Get-Module
import-Module AzureAD
# Parameters
$aadAppId = "ea954743-####-4025-bc90-############" # AAD app id
$aadAppRedirectUri = "http://localhost" # AAD app redirect URI
$aadTenantId = "46fe5ca5-####-4e42-92e9-############" # tenant id
# Load Microsoft.Identity.Client.dll
Add-Type -Path "C:\Program Files\WindowsPowerShell\Modules\AzureAD\2.0.2.135\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
# Get access token
$ctx = [Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext]::new("https://login.microsoftonline.com/$aadTenantId")
$redirectUri = New-Object -TypeName System.Uri -ArgumentList $aadAppRedirectUri
$platformParameters = New-Object -TypeName Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters -ArgumentList ([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
$accessToken = $ctx.AcquireTokenAsync("https://api.businesscentral.dynamics.com", $aadAppId, $redirectUri, $platformParameters).GetAwaiter().GetResult().AccessToken
Write-Host -ForegroundColor Cyan 'Authentication complete - we have an access token for Business Central, and it is stored in the $accessToken variable.'
#Get list of environments
$response = Invoke-WebRequest `
-Method Get `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
#List user sessions
$environmentName = "TEST"
$response = Invoke-WebRequest `
-Method Get `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
#Get Session Details
$sessionId = "145197"
$response = Invoke-WebRequest `
-Method Get `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions/$sessionId" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
#Stop/Delete Session
$response = Invoke-WebRequest `
-Method Delete `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions/$sessionId" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
$response = Invoke-WebRequest `
-Method Delete `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions/$sessionId" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host "Responded with: $($response.StatusCode) $($response.StatusDescription)"
When I try to delete a session, it gives the following error.
PS C:\WINDOWS\system32> #Stop/Delete Session
$response = Invoke-WebRequest `
-Method Delete `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions/$sessionId" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
ConvertFrom-Json : Cannot convert 'System.Byte[]' to the type 'System.String' required by parameter
'InputObject'. Specified method is not supported.
At line:6 char:46
+ Write-Host (ConvertTo-Json (ConvertFrom-Json $response.Content))
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [ConvertFrom-Json], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ConvertFromJsonComm
and
PS C:\WINDOWS\system32> $response = Invoke-WebRequest `
-Method Delete `
-Uri "https://api.businesscentral.dynamics.com/admin/v2.11/applications/businesscentral/environments/$environmentName/sessions/$sessionId" `
-Headers #{Authorization=("Bearer $accessToken")}
Write-Host "Responded with: $($response.StatusCode) $($response.StatusDescription)"
Responded with: 204 No Content
The scope of the token looks alright, or at least the same as what I have setup in the Azure app, which is delegated permissions. Assuming these are the correct permissions.
"scp": "Financials.ReadWrite.All user_impersonation",
Any help greatly appreciated!
Apologies, it turns out it is working. A '204 No Content' indicates a successful completion for the Delete method. My confusion stemmed from expecting a response from the delete method when there was none.
Delete Items - Business Central API

powershell core 7.0.3 Az.Account PSADServicePrincipal appRoles and oauth2permissions

I have windows powershell 5.1 script block like the following that successfully retrieves appRoles and oauth2permissions.
import-module -name AzureAD
if ($null -eq $mycredentials) { $mycredentials = Get-Credential }
$azConnectionContext = Connect-AzureAD -Credential $mycredentials
# $svp = Get-AzureADServicePrincipal -Filter "DisplayName -eq 'Microsoft Graph' } # not working, why ???
$svp = Get-AzureADServicePrincipal -All $true | ? { $_.DisplayName -eq 'Microsoft Graph }
$appRoles = $svp.AppRoles; $oauth2permissions = $svp.Oauth2Permissions
I'm trying to convert to powershell core 7 script block like the following and i'm unable to retrive appRoles and oauth2permissions because the PSADServicePrincipal type doesn't expose those properties.
import-module -name Az.Accounts
$azConnectionContext = Connect-AzAccount
$svp = Get-AzADServicePrincipal -DisplayName 'Microsoft Graph' }
$appRoles = $svp.AppRoles; $oauth2permissions = $svp.Oauth2Permissions # both of these fail
Question - anyone know how i get at azure ad service principal appRoles and oauth2permissions using powershell core 7.0.3 apis and types?
Instead of:
$svp.AppRoles;
Use:
$svp.AppRole;
$svp.Oauth2Permissions should work. Type should be Microsoft.Azure.PowerShell.Cmdlets.Resources.Models.Api16.OAuth2Permission.
To your last question, remove-module only removes a module for the current session. You need to run Uninstall-Module instead.
There is an Uninstall-AzModule function here that might help you: https://learn.microsoft.com/en-us/powershell/azure/uninstall-az-ps?view=azps-4.6.1

Passing an array to Get-Job

I am having trouble getting an array passed to a scriptblock in Start-Job. Can you tell me what I might be doing wrong?
$bounceBlock = {
param(
[string[]]$list,
[System.Management.Automation.PSCredential]$cred
)
Add-PSSnapin VMware.VimAutomation.Core | Out-Null
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope User -InvalidCertificateAction Ignore -Confirm:$false | Out-Null
Connect-VIServer -Server servername -Credential $cred -AllLinked
Get-VM -Name $list
}
if ($targets) {
$activeTargets = $targets | Get-Random -Count $prodTargets.Count
$counter = [pscustomobject] #{Value = 0}
$groupSize = 50
$groups = $activeTargets | Group-Object -Property {[math]::Floor($counter.Value++ / $groupSize)}
$connection = Connect-VIServer -Server servername -Credential $cred -AllLinked
if ($connection -match "servername") {
foreach ($group in $groups) {
while ((Get-Job -State Running).Count -ge 5) {
Start-Sleep -Seconds 5
}
Start-Job -ScriptBlock $bounceBlock -ArgumentList (,$group.Group.ServerName),$cred
}
Disconnect-VIServer * -Force -Confirm:$false
}
}
I basically split an array into chunks of 50 (working) then try to run them as jobs. The error I get looks like it's trying to run Get-VM for a single server, named all 50 values appended together.
I am certainly no expert with PS, but first to address how you're passing in the appended list of servers; I do something similar with Azure VMs using Get-AzureVM and I pass in my list of VM names in a System.Array to functions or cmdlets such as a variable such as $theVMs= "MyServer1","MyServer2","MyServer3"
and then I execute a foreach loop over ($vm in $theVMs) and then perform the actions such as Get-VM sequentially. I do this sequentially since PS has some much lower limits, 5 per my experience, doing this via a parallel for loop.
A typical way I interact with the VMs remotely and create a PS Job per each is to use
$uri = Get-AzureWinRMUri -ServiceName $svc -Name $vmname
Invoke-Command -ConnectionUri $uri -Credential $creds **-JobName
$jobname**
-ArgumentList $vmname -ScriptBlock {
param([string]$thevm) ...
}
This requires the InstallWinRMCertAzureVM.ps1 script which is discussed and available at http://blogs.technet.com . I use this for between 30 servers regularly.
Just wanted everyone to know in case they run into a similar problem, this is an issue with running Get-VM, and it exists whether running it in a job or workflow. VMWare is aware of this issue.

Powershell Script to Start Service if it is Stopped and wait for minute and send an email notification

I am very new to Powershell and in learning stage, I have tried to create an script to do automate below task. This script is not working as i am expected. Could you please review it and give me some help on it.
My task is,
I am trying to find out SQL Services (more than one SQL services in multiple servers) which are in stopped state and trying to start it, Waiting for an minute to complete the service start and verifying the service status again. If still it is stopped state i am trying to sending an email to setup of people for an action.
Could you please review the below code and correct the mistake, i tried to find it but unable to do
#Define servers & Services Variables
$Servers = GC "E:\Bhanu\SQLServer.txt"
$Services = GC "E:\Bhanu\SQLService.txt"
#Function Call
Function ServiceStatus ($Servers, $Services)
{
foreach ($Server in $Servers)
{
foreach ($Service in $Services)
{
$Servicestatus = get-service -ComputerName $Server -Name $Service
if ($Servicestatus.Status -eq "Stopped")
{
Start-service $Service
Start-Sleep -Seconds 60
$ServiceStatus1 = Get-Service -ComputerName $Server -Name $Service
if ($Servicestatus1.Status -eq "Stopped")
{
FuncMail -To “abc#gmail.com” -From “abc#gmail.com” -Subject $Server + $Service "fails to Start, Take immediate Action to avoid Impact” -Body $ServiceName "Service fails to Start, Take immediate Action to avoid Impact” -smtpServer “servername”
}
}
}
}
}
function FuncMail
{
#param($strTo, $strFrom, $strSubject, $strBody, $smtpServer)
param($To, $From, $Subject, $Body, $smtpServer)
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$msg.From = $From
$msg.To.Add($To)
$msg.Subject = $Subject
$msg.IsBodyHtml = 1
$msg.Body = $Body
$smtp.Send($msg)
}
servicestatus $Servers $Services
Please let me know if you need anything here from my end
Hi this isn't the best approach and i'm doing it in quick way.
note %=foreach-object; ?=Where-Object.
You have to save your password on one file if your smtp-server require authentication otherwise don't run it using read-host -assecurestring | convertfrom-securestring | out-file "C:\Secure\Password.txt"
I'm also assuming you have your servers saved on one file.
My solution is to start all sql server service if you want to start specific just save the service name on one file on separate line.
The code to execute bellow.
#Loading Server and service details
$Services=Get-content C:\PS\Service.txt
$servidores=get-content C:\PS\Servers\Servers.txt
#Loading Mail credential
$Mailpasswordpath="C:\PS\Securestring.txt"
$Mailusername="DOmain\User"
$password=cat $Mailpasswordpath |ConvertTo-Securestring
$Cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Mailusername,$password
$servidores|Foreach-Object{Get-Service -ComputerName $_ -Name $Services }| #Get the services running on all servers
Where-Object{$_.Status -eq "Stopped"}| #Which status is equal stopped
Foreach-Object{
$_.Start(); #try to start
Start-Sleep -Seconds 60; #wait one minute
$_.Refresh(); #refresh then service to update status
#validate is status still stopped
if($_.Status -eq "Stopped")
{
#LOADING Mail details
$To="user#domain.com"
$subject="$($_.MachineName) $($_.Name) fails to Start, Take immediate Action to avoid Impact"
$From="ServiceStatus#domain.com"
$smtp="Server.domain.com"
$body="$($_.Name) Service fails to Start, Take immediate Action to avoid Impact"
#Sending email to notify
Send-MailMessage -To $To -Subject $subject -From $From -SmtpServer $smtp -Body $body -Credential $Cred
}
}
P.S: It's not the best approach I only decide to solve this problem. if you want we can create a function together later just test it first.

Unable to query [adsisearcher] for trusted domains (PowerShell)

I wanted to query [adsisearcher] to get me the OU info for a few servers for servers in trusted & non trusted domains.
$session = New-PSSession -ComputerName icvmm02
Invoke-Command -Session $session -ScriptBlock {
$compname= (Get-WmiObject "Win32_Computersystem" -namespace "root\CIMV2" -computername $comp).name
$searcher = [adsisearcher]"(&(ObjectCategory=computer)(Name=$compname))"
$ou= $searcher.FindOne() | Select-Object path
$serverou = $ou.path
}
$adou= (Invoke-Command -Session $session -ScriptBlock { $serverou })
Get-PSSession | Remove-PSSession
for servers in trusted domains im passing a $cred = get credentials while creating a pssession, but when i run
$compname= (Get-WmiObject "Win32_Computersystem" -namespace "root\CIMV2" -computername $comp).name
$searcher = [adsisearcher]"(&(ObjectCategory=computer)(Name=$compname))"
$ou= $searcher.FindOne() | Select-Object path
it gives me an error as
Exception calling "FindOne" with "0" argument(s): "An operations error occurred.
"
At line:1 char:27
+ $ou= $searcher.FindOne <<<< () | Select-Object path
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
$serverou = $ou.path
Could some one please help me in sorting this out.
I don't the cause but the ADSI interface just doesn't work in remote sessions. I can't even get the DN of the domain of a computer in my domain. I can get this to run locally but not remotely:
icm { ([adsi]"").distinguishedName } #works
icm -Session $s -ScriptBlock { ([adsi]"").distinguishedName } #doesn't work
Looks like there's a problem with the FindOne method call - you can find out more about the $searcher object with this;
$searcher | gm
the findOne method should be there with a list of the parameters it takes.
Though, I've just tried it on the type:
[adsisearcher] | gm | sort name
and there's no FindOne method - are you sure it's a method of adsisearcher?

Resources