How to post a message to Slack from Powershell - powershell-2.0

I'm looking for a simple example of PowerShell code that uses HttpClient to post to a Slack channel.

Add-Type -AssemblyName System.Net.Http
$http = New-Object -TypeName System.Net.Http.Httpclient
$message = "Hello world."
$httpMessage = "{""text"": """ + $message + """}";
$content = New-Object -TypeName System.Net.Http.StringContent($httpMessage)
$httpResult = $http.PostAsync("https://hooks.slack.com/services/your_channel_url_here", $content).Result

Related

Getting Error while updating environments level variable on Azure devOps release

I am trying to update the Environment level variable on Azure DevOps Release using below code.
$url = "$(System.TeamFoundationServerUri)$(System.TeamProjectId)/_apis/Release/releases/$(Release.ReleaseId)/environments/$(RELEASE.ENVIRONMENTID)?api-version=7.0"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers #{
Authorization = "Bearer $(System.AccessToken)" # Provided by ADO thanks to OAuth checkbox
}
$pipeline.variables.Root.value = 'Test'
$T1 = [pscustomobject] #{ scheduledDeploymentTime = $null ; comment = $null ; variables = $pipeline.variables }
$json = #($T1) | ConvertTo-Json -Depth 99
Write-Host $json
Invoke-RestMethod -Uri $url -Method PATCH -Body $json -ContentType "application/json" -Headers #{Authorization = "Bearer $(System.AccessToken)"}
Error I am getting:
enter image description here.
What am I doing wrong?

Azure HTTP Trigger. How to avoid everytime the login

I have an Azure HTTP trigger function.
And it all works, except that I am executing everytime the slow
Connect-ExchangeOnline -Credential $Credential
How can I re-use the security token so it is only once slow.
And instead of using a normal login account, can I also use an applicationID and secret?
using namespace System.Net
param($Request, $TriggerMetadata)
$body = #{}
$user = "xxx#contoso.com"
$password = "example_password"
$securePassword = $password | ConvertTo-SecureString -AsPlainText -Force
$Credential = new-Object System.Management.Automation.PSCredential($user,$securePassword)
try {
Connect-ExchangeOnline -Credential $Credential
$filter = $Request.Body
$wildCard = $filter.wildCard
$SharedMailboxes = Get-Mailbox -RecipientTypeDetails SharedMailbox -ResultSize:1000 $wildcard|
Select-Object Identity,User,AccessRights,SamaccountName, PrimarySmtpAddress,City ,UsageLocation,IsDirSynced, DisplayName,HiddenFromAddressListsEnabled, GrantSendOnBehalfTo, ExmployeeID
$body.values = $SharedMailboxes
}
catch {
Write-Error $_.Exception.Message
$body.error = $_.Exception.Message
}
finally {
Disconnect-ExchangeOnline -Confirm:$false
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
Body = $body
})

Ms Graph RestAPI create team 404

the first try catch works, he is adding the ms graph AD group in office365.
But the second try catch (converting the group to a Team does not work. I receive an 404 error??
The groupID exists on the server I notice.
Whats going wrong to get an 404?
I did add a secret token on the azure control panel.
The script has the token, appid and tenantid in live time.
also: the tenant has graph roles like group.ReadWriteAll. same for Teams and Directories.
Clear-Host
$env:graphApiDemoAppId = "" # Replace with your Azure AD app id
$env:graphApiDemoAppSecret = "" # Replace with your Azure AD app secret
$env:tenantId = "" # Replace with your Azure AD tenant ID
$oauthUri = "https://login.microsoftonline.com/$env:tenantId/oauth2/v2.0/token"
# Create token request body
$tokenBody = #{
client_id = $env:graphApiDemoAppId
client_secret = $env:graphApiDemoAppSecret
scope = "https://graph.microsoft.com/.default"
grant_type = "client_credentials"
}
# Retrieve access token
$tokenRequest = Invoke-RestMethod -Uri $oauthUri -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenBody -UseBasicParsing
# Save access token
$accessToken = ($tokenRequest).access_token
$headers = #{
"Authorization" = "Bearer $accessToken"
"Content-type" = "application/json"
}
try
{
# Create group request body
$groupName = "Test_Kenvh16"
$groupBodyParams = #{
displayName = $groupName
description = $groupName
mailNickName = $groupName
groupTypes = #("Unified")
mailEnabled = $true
securityEnabled = $false
visibility = "Private"
}
$groupBody = ConvertTo-Json -InputObject $groupBodyParams
$newGroup = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/groups" -Method POST -Headers $headers -Body $groupBody
$groupId = $newGroup.id
Write-Host "group created:" $groupName "id:" $groupId
try
{
#convert group to team..
$teamBodyParams = #{
memberSettings = #{
allowCreateUpdateChannels = $true
}
messagingSettings = #{
allowUserEditMessages = $true
allowUserDeleteMessages = $true
}
funSettings = #{
allowGiphy = $true
giphyContentRating = "strict"
}
}
$teamBody = ConvertTo-Json -InputObject $teamBodyParams
$teamUri = "https://graph.microsoft.com/v1.0/groups/" + $groupId + "/team"
$newTeam = Invoke-RestMethod -Uri $teamUri -Method POST -Headers $headers -Body $teamBody
$teamId = $newTeam.id
}
catch
{
Write-Host "createTeam ExceptionMessage:" $_.Exception.Message
Write-Host "createTeam StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "createTeam StatusDescription:" $_.Exception.Response.StatusDescription
}
}
catch
{
Write-Host "createGroup ExceptionMessage:" $_.Exception.Message
Write-Host "createGroup StatusCode:" $_.Exception.Response.StatusCode.value__
Write-Host "createGroup StatusDescription:" $_.Exception.Response.StatusDescription
}

I need a way to authenticate sharepointonline api connection without user consent using ARM or any powershell

I want automation to authenticate sharepoint online api connection without user consent in Azure as I want to run the code in azuredveops pipeline and the code which I got got does open a custom form and ask for user consent.It is good if I don't have to run it through devops pipeline but in my case yes I need to run authorization through code without user/graphical intervention
I have tried below code which works fine on my local but as I explained,it needs user consent which won't work in azuredevops pipeline world
[string] $ResourceGroupName = '*****',
[string] $ResourceLocation = '******',
[string] $api = 'office365',
[string] $ConnectionName = 'SharepointOnline',
[string] $subscriptionId = '*****'
)
#OAuth window for user consent
Function Show-OAuthWindow {
Add-Type -AssemblyName System.Windows.Forms
$form = New-Object -TypeName System.Windows.Forms.Form -Property #{Width=600;Height=800}
$web = New-Object -TypeName System.Windows.Forms.WebBrowser -Property #{Width=580;Height=780;Url=($url -f ($Scope -join "%20")) }
$DocComp = {
$Global:uri = $web.Url.AbsoluteUri
if ($Global:Uri -match "error=[^&]*|code=[^&]*") {$form.Close() }
}
$web.ScriptErrorsSuppressed = $true
$web.Add_DocumentCompleted($DocComp)
$form.Controls.Add($web)
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() | Out-Null
}
#login to get an access code
#Login-AzureRmAccount
#select the subscription
$ResourceLocation = (Get-AzureRmResource -ResourceGroupName CI | Select-Object Location)[0].Location
$subscription = Select-AzureRmSubscription -SubscriptionId $subscriptionId
#Get the connection and create if wasn't already created
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName -ErrorAction SilentlyContinue
if(-not $connection) {
$connection = New-AzureRmResource -Properties #{"api" = #{"id" = "subscriptions/" + $subscriptionId + "/providers/Microsoft.Web/locations/" + $ResourceLocation + "/managedApis/" + $api}; "displayName" = $ConnectionName; } -ResourceName $ConnectionName -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -Location $ResourceLocation -Force
}
#else get the connection
else{
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
}
Write-Host "connection status: " $connection.Properties.Statuses[0]
$parameters = #{
"parameters" = ,#{
"parameterName"= "token";
"redirectUrl"= "https://online.microsoft.com/default/authredirect"
}
}
#get the links needed for consent
$consentResponse = Invoke-AzureRmResourceAction -Action "listConsentLinks" -ResourceId $connection.ResourceId -Parameters $parameters -Force
$url = $consentResponse.Value.Link
#prompt user to login and grab the code after auth
Show-OAuthWindow -URL $url
$regex = '(code=)(.*)$'
$code = ($uri | Select-string -pattern $regex).Matches[0].Groups[2].Value
Write-output "Received an accessCode: $code"
if (-Not [string]::IsNullOrEmpty($code)) {
$parameters = #{ }
$parameters.Add("code", $code)
# NOTE: errors ignored as this appears to error due to a null response
#confirm the consent code
Invoke-AzureRmResourceAction -Action "confirmConsentCode" -ResourceId $connection.ResourceId -Parameters $parameters -Force -ErrorAction Ignore
}
#retrieve the connection
$connection = Get-AzureRmResource -ResourceType "Microsoft.Web/connections" -ResourceGroupName $ResourceGroupName -ResourceName $ConnectionName
Write-Host "connection status now: " $connection.Properties.Statuses[0]
You must first create a Automation account with AzureRunAs credentials. Then create your Runbook inside your automation account.
About AzureRunAs account - docs
My first Runbook - docs
From Azure Devops i found this blog which can be of help

How do I get a LinkedIn request token?

Hey I'm trying to use LinkedIn's OAuth in PHP. I'm stuck at the first step of getting a request token. All I know is you post some values to their server and get your token back. So i post the documented args to 'https://api.linkedin.com/uas/oauth/requestToken' and I get slapped with a 400 error.
here's the request:
$postArr = array();
//$postArr["oauth_callback"] = ""; idk they said this was optional...
$postArr["oauth_consumer_key"] = "ForBritishEyesOnly"; //is this the application secret key or the api key?
$postArr["oauth_nonce"] = "UltraRandomNonceFTW";
$postArr["oauth_timestamp"] = time();
$postArr["oauth_signature_method"] = "HMAC-SHA1"; //lolwut
$postArr["oauth_version"] = "1.0";
$params = array('http'=>array('method'=>'post','content'=>http_build_query($postArr)));
$context = stream_context_create($params);
$stream = file_get_contents('https://api.linkedin.com/uas/oauth/requestToken', false, $context);
I don't think my POST args are correct but ANY help is very appreciated -- I just don't want resort to use someone else's library to solve this.
-------EDIT: ATTEMPT 2 per James' input ---------
ok so here im making a call to the test link you sent me. i'm actually able to get a response back, but it doesnt like my signature (big surprise, i know). So just how bad did I screw up the encryption?
//setup GET args
$url = "http://term.ie/oauth/example/request_token.php?";
$url .= "oauth_version=1.0&";
$url .= "oauth_nonce=" . rand(0, 100000) . "&";
$url .= "oauth_timestamp=" . time() . "&";
$url .= "oauth_consumer_key=key&";
$url .= "oauth_signature_method=HMAC-SHA1&";
//encrypt the request according to 'secret'
$sig = urlencode(base64_encode(hash_hmac("sha1", $url, "secret")));
//append the url encoded signature as the final GET arg
$url .= "oauth_signature=" . $sig;
//do it to it
echo file_get_contents($url);
EDIT by James
Try:
//setup GET args
$url = "http://term.ie/oauth/example/request_token.php?";
$url .= "oauth_consumer_key=key&";
$url .= "oauth_nonce=" . rand(0, 100000) . "&";
$url .= "oauth_signature_method=HMAC-SHA1&";
$url .= "oauth_timestamp=" . time() . "&";
$url .= "oauth_version=1.0&";
I'm on cloud nine. Decided to revisit this problem and got it to work. Here is some very bare bones PHP to build a token request for LinkedIn (it outputs an anchor tag)
<?php
$endpoint = "https://api.linkedin.com/uas/oauth/requestToken";
$key = "YourAPIKey";
$secret = "YourAPISecret";
$params = array(
"oauth_version" => "1.0",
"oauth_nonce" => time(),
"oauth_timestamp" => time(),
"oauth_consumer_key" => $key,
"oauth_signature_method" => "HMAC-SHA1"
);
function SortedArgumentString($inKV)
{
uksort($inKV, 'strcmp');
foreach ($inKV as $k => $v)
$argument[] = $k."=".$v;
return implode('&', $argument);
}
$baseString = "GET&" . urlencode($endpoint) . "&" . urlencode(SortedArgumentString($params));
$params['oauth_signature'] = urlencode(base64_encode(hash_hmac('sha1', $baseString, $secret."&", TRUE)));
echo "<a href=\"" . $endpoint . "?" . SortedArgumentString($params) . "\">Get Token<a/><br/>";
?>
oauth_consumer_key is a value that LinkedIn should have assigned to your app. Did you register with them?
oauth_nonce should be different for each request to prevent replay-attacks.
If you're using HMAC-SHA1 you'll need to add the oauth_signature field yourself. Creating the signature manually is a total PITA.
There's also a lot of Base64 encoding to do (with the added bonus of some special OAuth quirks). I suggest you read the spec.
There is a test server and client at this link. It's quite useful when you're struggling to get the protocol right.

Resources