Attempting to Change PSK of SSID with Meraki API via Powershell

SOLVED
Lucas
Conversationalist

Attempting to Change PSK of SSID with Meraki API via Powershell

I am trying to execute a PUT script in PS, below is the function.  When I run the script I'm receiving a 308 error.  

 

[Net.ServicePointManager]:: SecurityProtocol = [Net.SecurityProtocolType]::Tls12

 

#Change Guest Wifi Password
$MerakiApiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$NETWORK_ID = "XXXXXXXXXXXXXXXX"
$MerakiUrl = "https://dashboard.meraki.com/api/v0/networks/$NETWORK_ID/ssids/6"
$headers = @{}
$headers.Add("X-Cisco-Meraki-API-KEY",$MerakiApiKey)
$headers.Add("ContentType",'application/json')
$jbody = '{"psk": "NewPassword"}'

Invoke-RestMethod -Method put -Uri $MerakiUrl -Headers $headers -Body $jbody

 

When I run the above script I receive the below.

 

Invoke-RestMethod : The remote server returned an error: (308).
At line:9 char:1
+ Invoke-RestMethod -Method put -Uri "https://dashboard.meraki.com/api/ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

 

I have tried testing the functionality of the PUT command in POSTMAN and it works flawlessly. I know the documentation says to use https://api.meraki.com/api/v0/ as the base url but when i change the url to that, the script still fails with the same error.

 

I tried capturing the response I get back using the below code:

$resp = try { Invoke-RestMethod -Method put -Uri $MerakiUrl -Headers $headers -Body $jbody } catch { $_.Exception.Response }
$resp

 

Here is the output of the above:

Output.PNG

 

Any insight would great.

1 ACCEPTED SOLUTION
Jukka
New here

 

Hi,

 

Try to change the base url to your tenant URL. You can get this url when you login to https://dashboard.meraki.com. It's like https://nXXX.meraki.com. Powershell doesn't seem to like HTTP 308 permanent redirect.

 

I'm using this code to update the PSK:

 

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11
#Meraki API KEY
$api_key = "API_KEY"
#Meraki Network URL
$network_id = "NETWORK_ID"
#Base API URL
$api = @{
    "endpoint" = 'https://api.meraki.com/api/v0'
}
#API URL for SSID PSK Change XXX
$api_put = @{
    "endpoint" = 'https://nXXX.meraki.com/api/v0'
}

$header_org = @{
    "X-Cisco-Meraki-API-Key" = $api_key
    "Content-Type" = 'application/json'
}
# PSK = New password
$data = @{
    "psk" = 'NewPassword12345'
}
#Convert data to Json format
$jbody = ConvertTo-Json -InputObject $data
#URL Network_ID and SSID number
$api.ssid = "/networks/$network_id/ssids/2"
#Combine base api_put URL and $api.ssid
$Merakiuri = $api_put.endpoint + $api.ssid
Invoke-RestMethod -Method Put -Uri $Merakiuri -Headers $header_org -Body $jbody -Verbose

 

View solution in original post

6 REPLIES 6
Jukka
New here

 

Hi,

 

Try to change the base url to your tenant URL. You can get this url when you login to https://dashboard.meraki.com. It's like https://nXXX.meraki.com. Powershell doesn't seem to like HTTP 308 permanent redirect.

 

I'm using this code to update the PSK:

 

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11
#Meraki API KEY
$api_key = "API_KEY"
#Meraki Network URL
$network_id = "NETWORK_ID"
#Base API URL
$api = @{
    "endpoint" = 'https://api.meraki.com/api/v0'
}
#API URL for SSID PSK Change XXX
$api_put = @{
    "endpoint" = 'https://nXXX.meraki.com/api/v0'
}

$header_org = @{
    "X-Cisco-Meraki-API-Key" = $api_key
    "Content-Type" = 'application/json'
}
# PSK = New password
$data = @{
    "psk" = 'NewPassword12345'
}
#Convert data to Json format
$jbody = ConvertTo-Json -InputObject $data
#URL Network_ID and SSID number
$api.ssid = "/networks/$network_id/ssids/2"
#Combine base api_put URL and $api.ssid
$Merakiuri = $api_put.endpoint + $api.ssid
Invoke-RestMethod -Method Put -Uri $Merakiuri -Headers $header_org -Body $jbody -Verbose

 

Lucas
Conversationalist

Your example worked great! Thank you so much for the information! I was able to use your script and input my specific network information and it worked.

Cassidy
Conversationalist

I'd like to note that this answer also helped with a Google Apps Script project. The base url had to be the tenant URL there, just as in PowerShell. Apps Script has a UrlFetchApp.fetch() method which does have a 'followRedirects' option, but it's already set by default to true and even including it explicitly in the function still didn't allow the PUT to succeed. Only using the tenant url (e.g. NXXX.meraki.com) for a PUT would work.

Note: I have not attempted to parse out the redirect headers in Apps Script to rebuild a new request, as suggested for PowerShell by MarkD_BT below -- I'm happy it's working as is and can move on.

Thanks very much for sharing this tip!
PJV
Conversationalist

Jukka,

 

First thank you for sharing your script its very much appreciated.

 

Wondering if you can help confirm a few of the variables we need to populate as I'm currently getting (404) Not Found.

 

API_KEY should be the 40 character key I generated on my dashboard after enabling API access.

 

NETWORK_ID the name of the overall network(switches, access points, security appliances) not one level deeper that combines the network name and the word wireless "network-wireless"? 

 

Nxxx replace the thre xxx with three digits on the url I see when connected to my dashboard.

 

$api.ssid = "/networks/$network_id/ssids/4"  You had the #2 I have changed this to #4 as the SSID I want to modify is the forth is this a correct assumption?

 

Hoping you or someone night give me a clue and push me in the right direction.

 

MarkD_BT
Getting noticed

Hello PVJ,

 

the api_key is the 40 character key that you generated

Network_ID is a unique id for the network which can be found by utilising the api to call network information

https://api.meraki.com/api/v0/organizations/[organizationId]/networks

It will be similar to this format L_647392446434509000

if you need the org id that is using this url https://api.meraki.com/api/v0/organizations

You can get the full list of SSIDs again your site using the following url https://api.meraki.com/api/v0/networks/[networkId]/ssids

to make sure you are using the correct ssid number as the numbering starts at 0

so if your looking at the list via the webpage the 1st ssid is 0 then 1 and so on.

 

MarkD_BT
Getting noticed

Just to add if your using powershell you can tackle redirects in the following manner useful if your updating things accross multiple orgs with different shard names

 

$resource = "https://api.meraki.com/api/v0/networks/$networkId/devices/$serial"

 

$redirect = Invoke-WebRequest -Uri $resource -MaximumRedirection 0 -Method PUT -Header $header -Body $body
if ($redirect.StatusCode -eq 308)
{
$resourceRedirect = $redirect.Headers.Location
     Invoke-WebRequest -Uri $resourceRedirect -MaximumRedirection 0 -Method PUT -Header $header -Body $body  
}
}

Get notified when there are additional replies to this discussion.