I'm trying to create a powershell script that setups user "George" after installing RabbitMQ on a new machine.
I can't figure out why this script doesn't work.
The last step gives me a 404 {"error":"Object Not Found","reason":"\"Not Found\"\n"}
$secpasswd = ConvertTo-SecureString 'guest' -AsPlainText -Force
$credGuest = New-Object System.Management.Automation.PSCredential ('guest', $secpasswd)
$secpasswd2 = ConvertTo-SecureString 'george' -AsPlainText -Force
$credAdmin2 = New-Object System.Management.Automation.PSCredential ('george', $secpasswd2)
$body = #{
'password' = 'george'
'tags' = 'administrator'
} | ConvertTo-Json
$vhosts1 = ''
$vhosts1 = Invoke-RestMethod 'http://localhost:15672/api/users/george' -credential $credGuest -Method Put -ContentType "application/json" -Body $body
write '1:' $vhosts1
$vhosts2 = Invoke-RestMethod 'http://localhost:15672/api/permissions/%2f/' -Method get -credential $credAdmin2
write '2:' $vhosts2
$body2 = #{
'username' = 'george'
'vhost' = '/'
'configure' = '.*'
'write' = '.*'
'read' = '.*'
} | ConvertTo-Json
write '3:' $body2
$vhosts3 = Invoke-RestMethod 'http://localhost:15672/api/permissions/%2f/george' -credential $credGuest -Method Put -ContentType "application/json" -Body $body2
write '4:' $vhosts3
I've also tried formatting the last step like this:
http://localhost:15672/api/permissions/george
Same 404 error.
I've tried about 20,000 different ways of sending the command in. From matching other examples perfectly to trying some abstract art and voodoo magic. While watching the managment tool for RabbitMQ I can see George is created. And he has an empty vhost. So the first 3 steps work perfectly.
Alright man, you know that I love you, because I'd never heard of RabbitMQ before tonight. In the last hour, I've installed it on my Windows machine, and now have used this awesome guide here to the API and kind of learned about how it works.
So, when I run your same process step by step , I see everything happen as you state:
George gets created:
Since your second step is listing the current permissions of the user running the API call, I next see output of the guest account, which has full perms. Then onto step 3, which builds the target permissions for George.
username : george
write : .*
read : .*
configure : .*
vhost : /
From here, Step 4. When I run this step manually after the previous step...it works! However, if I run this too quickly, if I run the whole script at once, I will get a 404 error. It seems that behind the scenes in RabbitMQ a slight pause is needed for the files to be updated with the new user. When I deleted the user and tried the whole script again too quickly, I got 404's for every step, pretty much.
However, if I add a little Start-Sleep 5 to pause 5 seconds...
The whole process completed. The key place to add a pause is after Step 1 and it seems to need about four or five seconds.
Making it pretty
Now of course, I couldn't stop there, so I decided to add a few more minor pauses to improve output readability and also ensure that each operation completes. I added some purty looking "OK" messages after the step completes, and then added a finishing confirmation of permissions by doing one last API call for the current user.
Here's the completed output
Completed Script
$secpasswd = ConvertTo-SecureString 'guest' -AsPlainText -Force
$credGuest = New-Object System.Management.Automation.PSCredential ('guest', $secpasswd)
$secpasswd2 = ConvertTo-SecureString 'stephen' -AsPlainText -Force
$credAdmin2 = New-Object System.Management.Automation.PSCredential ('stephen', $secpasswd2)
$body = #{
'password' = 'stephen'
'tags' = 'administrator'
} | ConvertTo-Json
Write-host "About to create new user $(($body | ConvertFrom-Json).Password)..." -NoNewline
$vhosts1 = Invoke-RestMethod 'http://localhost:15672/api/users/stephen' -credential $credGuest -Method Put -ContentType "application/json" -Body $body
start-sleep 5
Write-host "OK" -ForegroundColor Green
Start-Sleep -Milliseconds 400
Write-Host '1: Results:' $vhosts1
$body2 = #{
'username' = 'stephen'
'vhost' = '/'
'configure' = '.*'
'write' = '.*'
'read' = '.*'
} | ConvertTo-Json
Write-Output "Desired perms for new user $(($body | ConvertFrom-Json).Password)" $body2
Write-host "Setting perms for new user..." -NoNewline
$vhosts3 = Invoke-RestMethod 'http://localhost:15672/api/permissions/%2f/stephen' -credential $credGuest -Method Put -ContentType "application/json" -Body $body2
Start-sleep 5
Write-host "OK" -ForegroundColor Green
Start-Sleep -Milliseconds 400
write '4:' $vhosts3
'Retrieiving perms for new user to confirm...'
Invoke-RestMethod 'http://localhost:15672/api/permissions/%2f/stephen' -Method get -credential $credAdmin2
Now I just hope I'll get a chance to use RabbitMQ ever again...
finally stumpled upon a powershell library someone else wrote for interacting with the RabbitMQ api.
https://github.com/mariuszwojcik/RabbitMQTools/blob/master/en-US/about_UnEsapingDotsAndSlashes.help.txt
I found out that certain versions of powershell replace %2f with the / before sending it to rabbit. If you use this guys functions found here:
https://github.com/mariuszwojcik/RabbitMQTools
Everything runs beautifully. Really great library he put together.
I'm late to this question. I love Powershell too, but I used a .bat file to run the native RabbitMQ commands as shown below. I needed to add a user, a vhost, and hook those two up. I wanted a script so any new developer could run it.
cd /D c:\Program Files\RabbitMQ Server\rabbitmq_server-3.6.14\sbin
echo cd completed
call rabbitmqctl add_user bts mypass
call rabbitmqctl set_user_tags bts administrator
call rabbitmqctl add_vhost base
call rabbitmqctl set_permissions -p base bts ".*" ".*" ".*"
Echo ----List Command to confirm results --------
call rabbitmqctl list_vhosts
call rabbitmqctl list_user_permissions bts
I suppose you could call these from Powershell too. I guess downside of this is that you have to be on the machine running RabbitMQ.
Related
I am experimenting with this https://forge-digital-twin.autodesk.io/# using the gitlab code. I can display it locally (without the engine or dataflow) but I can not gain an access token.
I am using the VSCode extension and I get the code 401 (Unauthorized) error if I try to create buckets etc (hence why I am trying to get an access code). However, when I request one using this:
curl -i -X POST 'https://developer.api.autodesk.com/authentication/v1/authenticate' -H 'Content-Type: application/x-www-form-urlencoded' -d 'client_id=-----' -d 'client_secret= ----' -d 'grant_type=client_credentials' -d 'scope=data:write data:read bucket:create bucket:delete'
I get this error:
Invoke-WebRequest : Cannot bind parameter 'Headers'. Cannot convert the "Content-Type:
application/x-www-form-urlencoded" value of type "System.String" to type
"System.Collections.IDictionary".
At line:1 char:90
... ticate' -H 'Content-Type: application/x-www-form-urlencoded' -d 'cl ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException
FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeWebRe
questCommand
I have no idea where I am going wrong and have tried everything I can think of.
Hope you can help, thanks :)
If you're seeing 401 issues when working with the Forge extension for Visual Studio Code, make sure that you have at least one "environment" configured with your Forge client ID and secret. When you activate the extension for the first time, it should ask you for the credentials automatically, but you can also add or edit the environments at any point by going to the Visual Studio Code preferences, and looking for "forge":
And then, in the Autodesk > Forge: Environments section, hit the Edit in settings.json link and edit the environments directly as JSON, creating a new object (with title, clientId, and clientSecret properties set) if needed:
Btw. VSCode provides intelli-sense support when editing the settings.json file, so you'll see exactly which properties are expected/available in each environment.
It defaults to Invoke-WebRequest.
Try to use Invoke-RestMethod like this:
$Body = #{
grant_type = "client_credentials"
client_id = ""
client_secret = ""
scope = "data:write data:read bucket:create bucket:delete"
}
$Headers = #{
'Content-Type' = 'application/x-www-form-urlencoded'
}
$response = Invoke-RestMethod -Method Post -Uri https://developer.api.autodesk.com/authentication/v1/authenticate' -Headers $Headers -Body $Body
Thanks in advance.
Quick brief, I work in a team managing multiple Microsoft CSPs (Partner Centers), every now and then somebody asks us to run a script that does specific activities or grab specific info from all 30 CSPs we manage and all customers under them.
Previously we used to keep all usernames, passwords, TenantIDs, WebApp IDs in a CSV file and we create a script that runs on every raw to get the required info for each CSP Automatically without prompting credentials using below command:
$credential = (New-Object –TypeName System.Management.Automation.PSCredential –argumentlist $AdminName ,(ConvertTo-SecureString $AdminPassword –AsPlainText –Force))
And then call it in all modules like the below:
#MSonline
Connect-Msolservice –Credential $Credential
#ExchangeOnline
$session = New-PSSession –ConfigurationName Microsoft.Exchange –ConnectionUri https://outlook.office365.com/powershell-liveid?DelegatedOrg=$Customerdomain –Credential $credential –Authentication Basic –AllowRedirection
Import-PSSession $Session
#Partner Center
Add-PCAuthentication -cspappID $NAtive_clientid -cspDomain $domain -credential $credentials
Connect-MsolService -Credential $credentials
Then MFA was applied on all CSPs, though secure, it presented a problem with automating our scripts. Every time we're asked to run a script we would have to login manually at least 1 time to enter our MFA credentials to be able to run the script on each CSP individually.
The Modules we usually connect to are:
PartnerCenter
MSOnline
CsOnline
AzureRM
AzureAD
Microsoft provided steps to work around this by using secure API Modules: https://learn.microsoft.com/en-us/powershell/partnercenter/secure-app-model?view=partnercenterps-1.5
I've created New APPs with new secrets and call backs , managed to get refresh token and integrated it in PartnerCenter module successfully as follows:
Connect-PartnerCenter -ApplicationId $NAtive_clientid -RefreshToken $refresh_token
Now I'm tying to do the same for the other Modules I'm addressing, as per the above document I could do the same for MS Online and for Azure AD simply by getting 3 other tokens (Graph Token , Azure AD token and Azure token)
$credential = Get-Credential
$refreshToken = 'Your-Refresh-Token-Value'
$azureToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://management.azure.com/ -Credential $credential -TenantId '<Your Tenant Id>'
$graphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.microsoft.com -Credential $credential -TenantId '<Your Tenant Id>'
$aadGraphToken = New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://graph.windows.net -Credential $credential -TenantId '<Your Tenant Id>'
#MS Module
Connect-MsolService -AdGraphAccessToken $aadGraphToken.AccessToken -MsGraphAccessToken $graphToken.AccessToken
# Az Module
Connect-AzAccount -AccessToken $azureToken.AccessToken -GraphAccessToken $graphToken.AccessToken -TenantId '<TenantId>'
# AzureRM Module
Connect-AzureRmAccount -AccessToken $azureToken.AccessToken -GraphAccessToken $graphToken.AccessToken -TenantId '<TenantId>'
When Applying this and running the below command I get an error:
New-PartnerAccessToken -RefreshToken $refreshToken -Resource https://management.azure.com/ -Credential $credential -TenantId '<Your Tenant Id>'
New-PartnerAccessToken : Cannot validate argument on parameter 'RefreshToken'. The argument is null or empty. Provide an argument
that is not null or empty, and then try the command again.
At line:1 char:38
+ New-PartnerAccessToken -RefreshToken $refreshToken -Resource https:// ...
+ ~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-PartnerAccessToken], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Store.PartnerCenter.PowerShell.Commands.NewPartnerAccessT
oken
After some investigation I found that the parameter "-resource" no longer exists as per the documentation: https://learn.microsoft.com/en-us/powershell/module/partnercenter/new-partneraccesstoken?view=partnercenterps-3.0
Yet as per the documentation related to MSOnline, it shows I should be able to use it : https://learn.microsoft.com/en-us/powershell/module/msonline/connect-msolservice?view=azureadps-1.0
Now I'm stuck without the resource parameter I can't get the tokens required to use the 3 modules.
My question, is there another way to use App ID, refresh token, secret, Tenant ID to authenticate using powershell without human interference , if not how can I make the above method work for other modules the same way I did with the partner center.
According to my research. if the version of your PartnerCenter module is larger than 2.0.1909.1, it has rplaced the Resource parameter with the Scopes parameter for the Connect-PartnerCenter and New-PartnerAccessToken cmdlets. So please use the following script to get access token
New-PartnerAccessToken -ApplicationId 'xxxx-xxxx-xxxx-xxxx' -Credential $credential -RefreshToken $refreshToken -Scopes 'https://graph.windows.net/.default' -ServicePrincipal -Tenant 'xxxx-xxxx-xxxx-xxxx'
I am looking something to setup alert notification when SQL agent is down, sometimes when windows patch apply or server get rebooted SQL Agent is not restarting even though we have set up SQL Agent properties Auto Restart SQL Server if it stops unexpectedly
Auto Restart SQL Server Agent if it stops unexpectedly.
I have also tried to setup services on Component service on server to at Recovery tab, First Failure Restart the service and also restarted service rebooted but didn't work.
Is it any way I can get the alert so I can restart service manually when it's Agent is down it it will trigger to restart the job when Agent it's down.
$AgentStatus = (Get-Service -ComputerName <CompName> -Name <SqlServerAgentName> | Where-Object {$_.Status -eq "Stopped"} | Measure-Object).Count
If($AgentStatus -eq 1){
Start-Service -Name SqlServerAgentName
$SMPTPort = <Specify port number>
$From = "email1#domain.com"
$To = "email2#domain.com"
$Subject = "The SQL Server Agent Service in $env:ComputerName has been restarted."
$Body = "The SQL Server Agent Service <SqlServerAgentName> was in a Stopped state and has been restarted."
$SMTPServer = "SMTP SERVER"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, $SMPTPort)
$SMTPClient.EnableSsl = $false
$SMTPClient.Send($From, $To, $Subject, $Body)}
You can try creating a batch file below which checks for service status. This sends an SMTP mail (using powershell) along with restarting service again.
for /F "tokens=3 delims=: " %%H in ('sc query "MyServiceName" ^| findstr " STATE"') do (
if /I "%%H" NEQ "RUNNING" (
powershell -ExecutionPolicy ByPass -Command Send-MailMessage -SmtpServer SMTPSERVER -To someone#domain.com -From noreply#domain.com -Subject Testing -Body Service_Not_Running
net start "MyServiceName"
)
)
Once you have the script ready, create a task scheduler to call the batch file. Run the scheduler every 1 hr or so.
I am trying to edit a VSTS wiki page via powershell and VSTS API and I am using this documentation as a reference.
When I try to edit an existing page, I get the following error:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"The page '<PAGE That I CREATED ALREADY>' specified in the add operation already exists in the wiki. Please specify a new page path.","typeName":"Microsoft.TeamFoundation.Wiki.Server.WikiPageAlreadyExistsException, Microsoft.TeamFoundation.Wiki.Server","typeKey":"WikiPageAlreadyExistsException","errorCode":0,"eventId":3000}
At line:32 char:11
+ $result = Invoke-RestMethod -Uri $uri -Method Put -ContentType "appli ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I can create a new page with the content there, but I am stumped as how would I update an existing wiki page. Please help.
Snippet of My Code:
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
# updates wiki page
$uri = "https://$($vstsAccount).visualstudio.com/$($projectName)/_apis/wiki/wikis/$($wikiIdentifier)/pages?path=/$($existingPage)&api-version=4.1"
$body = #"
{
"content": "Hello"
}
"#
$result = Invoke-RestMethod -Uri $uri -Method Put -ContentType "application/json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $body -Verbose
As the post Update wiki page REST API can not working in developer community, please make sure If-Match is contained in request header.
May I suggest a different approach?
The storage for a VSTS Wiki is a Git repo (see here). So you can clone the repo, change the files and push your changes back.
You can even use a VSTS build for this: the clone is implicit and there are many extensions to implement the push.
Make sure that the page version is included in the request header. Refer to this link for details: Pages - Create Or Update.
Version of the page on which the change is to be made. Mandatory for
Edit scenario. To be populated in the If-Match header of the request.
is it possible to call a Methode of a WCF Service in a bat file. We want to test if the WCF Service works correct after the Server was restartet.
There are no commands within the BAT file universe that will allow you to contact a WCF service directly, however you could use a BAT file to run an existing console program that can connect and interact with a WCF service. So the answer is both yes and no; not directly, but through a separate program yes.
If you need some simple, clickable way of accessing a WCF service, I'd go with a Powershell or VB script (assuming you're in a windows environment).
Maybe you will be able to use PowerShell? It would be easier then. Create script with content:
$url = 'http://yoursite.url/example.svc'
$action = "`"http://some.namespace/method`""
$SOAPRequest = [xml]#'heregoesxmlmessage'#
write-host "Sending SOAP Request To Server: $url"
$soapWebRequest = [System.Net.WebRequest]::Create($url)
$soapWebRequest.Headers.Add("SOAPAction", $action)
$soapWebRequest.ContentType = "text/xml;charset=`"utf-8`""
$soapWebRequest.Accept = "text/xml"
$soapWebRequest.Method = "POST"
write-host "Initiating Send."
$requestStream = $soapWebRequest.GetRequestStream()
$SOAPRequest.Save($requestStream)
$requestStream.Close()
write-host "Send Complete, Waiting For Response."
$resp = $soapWebRequest.GetResponse()
$responseStream = $resp.GetResponseStream()
$soapReader = [System.IO.StreamReader]($responseStream)
$ReturnXml = [Xml] $soapReader.ReadToEnd()
$responseStream.Close()
write-host "Response Received."
$ReturnXml.OuterXml | out-file ".\test.xml"
write-host $ReturnXml.OuterXml
As mentioned in the other answers Powershell is probably the best way to go using the New-WebServiceProxy cmdlet.
http://technet.microsoft.com/library/hh849841.aspx
Example from the link above:
PS C:\> $URI = "http://www.webservicex.net/uszip.asmx?WSDL"
PS C:\>$zip = New-WebServiceProxy -Uri $URI -Namespace WebServiceProxy -Class USZip
PS C:\> $zip.getinfobyzip(20500).table
CITY : Washington
STATE : DC
ZIP : 20500
AREA_CODE : 202
TIME_ZONE : E