Automated password for Guest wireless user

Solved
Josh_14
Conversationalist

Automated password for Guest wireless user

Hi all, Has anyone implemented or know a way to automate a password on weekly basis for a Meraki guest user account?

1 Accepted Solution
BrechtSchamp
Kind of a big deal

You could also use the dashboard API to change the password weekly with a timed script.

 

PUT Update the attributes of an SSID
 

HTTP REQUEST

PUT /networks/[networkId]/ssids/[number]

PARAMETERS

Parameter Description
nameThe name of an SSID
enabledWhether or not an SSID is enabled
authModeThe association control method for the SSID ('open', 'psk', 'open-with-radius', '8021x-meraki' or '8021x-radius')
encryptionModeThe psk encryption mode for the SSID ('wpa', 'wep' or 'wpa-eap')
pskThe passkey for the SSID. This param is only valid if the authMode is 'psk'
wpaEncryptionModeThe types of WPA encryption. ('WPA1 and WPA2' or 'WPA2 only')
splashPageThe type of splash page for the SSID ('None', 'Click-through splash page', 'Billing', 'Password-protected with Meraki RADIUS', 'Password-protected with custom RADIUS', 'Password-protected with Active Directory', 'Password-protected with LDAP', 'SMS authentication', 'Systems Manager Sentry', 'Facebook Wi-Fi', 'Google OAuth' or 'Sponsored guest'). This attribute is not supported for template children.
radiusServersThe RADIUS 802.1x servers to be used for authentication. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius'
hostIP address of your RADIUS server
portUDP port the RADIUS server listens on for Access-requests
secretRADIUS client shared secret
radiusCoaEnabledIf true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.
radiusFailoverPolicyThis policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable ('Deny access' or 'Allow access')
radiusLoadBalancingPolicyThis policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts ('Strict priority order' or 'Round robin')
radiusAccountingEnabledWhether or not RADIUS accounting is enabled. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius'
radiusAccountingServersThe RADIUS accounting 802.1x servers to be used for authentication. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius' and radiusAccountingEnabled is 'true'
hostIP address to which the APs will send RADIUS accounting messages
portPort on the RADIUS server that is listening for accounting messages
secretShared key used to authenticate messages between the APs and RADIUS server
ipAssignmentModeThe client IP assignment mode ('NAT mode', 'Bridge mode', 'Layer 3 roaming', 'Layer 3 roaming with a concentrator' or 'VPN')
useVlanTaggingDirect trafic to use specific VLANs. This param is only valid with 'Bridge mode' and 'Layer 3 roaming'
concentratorNetworkIdThe concentrator to use for 'Layer 3 roaming with a concentrator' or 'VPN'.
vlanIdThe VLAN ID used for VLAN tagging. This param is only valid with 'Layer 3 roaming with a concentrator' and 'VPN'
defaultVlanIdThe default VLAN ID used for 'all other APs'. This param is only valid with 'Bridge mode' and 'Layer 3 roaming'
apTagsAndVlanIdsThe list of tags and VLAN IDs used for VLAN tagging. This param is only valid with 'Bridge mode', 'Layer 3 roaming'
tagsComma-separated list of AP tags
vlanIdNumerical identifier that is assigned to the VLAN
walledGardenEnabledAllow access to a configurable list of IP ranges, which users may access prior to sign-on.
walledGardenRangesSpecify your walled garden by entering space-separated addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. 192.168.1.1/24 192.168.37.10/32 www.yahoo.com *.google.com). Meraki's splash page is automatically included in your walled garden.
minBitrateThe minimum bitrate in Mbps. ('1', '2', '5.5', '6', '9', '11', '12', '18', '24', '36', '48' or '54')
bandSelectionThe client-serving radio frequencies. ('Dual band operation', '5 GHz band only' or 'Dual band operation with Band Steering')
perClientBandwidthLimitUpThe upload bandwidth limit in Kbps. (0 represents no limit.)
perClientBandwidthLimitDownThe download bandwidth limit in Kbps. (0 represents no limit.)
 

HEADERS


X-Cisco-Meraki-API-Key
{{X-Cisco-Meraki-API-Key}}
Content-Type
application/json

BODY


{
    "name": "viaPostman935",
    "enabled": false,
    "splashPage": "None",
    "perClientBandwidthLimitUp": 0,
    "perClientBandwidthLimitDown": 0,
    "ssidAdminAccessible": false,
    "ipAssignmentMode": "NAT mode",
    "authMode": "open"
}

 

Here are the docs for that endpoint:

https://documenter.getpostman.com/view/897512/meraki-dashboard-api/2To9xm?version=latest#712cd25d-f8...

View solution in original post

63 Replies 63
PhilipDAth
Kind of a big deal
Kind of a big deal

Splash Access do a rotating WPA2-PSK option with a QR code for configuring guest WiFi devices.

https://www.splashaccess.com/

BrechtSchamp
Kind of a big deal

You could also use the dashboard API to change the password weekly with a timed script.

 

PUT Update the attributes of an SSID
 

HTTP REQUEST

PUT /networks/[networkId]/ssids/[number]

PARAMETERS

Parameter Description
nameThe name of an SSID
enabledWhether or not an SSID is enabled
authModeThe association control method for the SSID ('open', 'psk', 'open-with-radius', '8021x-meraki' or '8021x-radius')
encryptionModeThe psk encryption mode for the SSID ('wpa', 'wep' or 'wpa-eap')
pskThe passkey for the SSID. This param is only valid if the authMode is 'psk'
wpaEncryptionModeThe types of WPA encryption. ('WPA1 and WPA2' or 'WPA2 only')
splashPageThe type of splash page for the SSID ('None', 'Click-through splash page', 'Billing', 'Password-protected with Meraki RADIUS', 'Password-protected with custom RADIUS', 'Password-protected with Active Directory', 'Password-protected with LDAP', 'SMS authentication', 'Systems Manager Sentry', 'Facebook Wi-Fi', 'Google OAuth' or 'Sponsored guest'). This attribute is not supported for template children.
radiusServersThe RADIUS 802.1x servers to be used for authentication. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius'
hostIP address of your RADIUS server
portUDP port the RADIUS server listens on for Access-requests
secretRADIUS client shared secret
radiusCoaEnabledIf true, Meraki devices will act as a RADIUS Dynamic Authorization Server and will respond to RADIUS Change-of-Authorization and Disconnect messages sent by the RADIUS server.
radiusFailoverPolicyThis policy determines how authentication requests should be handled in the event that all of the configured RADIUS servers are unreachable ('Deny access' or 'Allow access')
radiusLoadBalancingPolicyThis policy determines which RADIUS server will be contacted first in an authentication attempt and the ordering of any necessary retry attempts ('Strict priority order' or 'Round robin')
radiusAccountingEnabledWhether or not RADIUS accounting is enabled. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius'
radiusAccountingServersThe RADIUS accounting 802.1x servers to be used for authentication. This param is only valid if the authMode is 'open-with-radius' or '8021x-radius' and radiusAccountingEnabled is 'true'
hostIP address to which the APs will send RADIUS accounting messages
portPort on the RADIUS server that is listening for accounting messages
secretShared key used to authenticate messages between the APs and RADIUS server
ipAssignmentModeThe client IP assignment mode ('NAT mode', 'Bridge mode', 'Layer 3 roaming', 'Layer 3 roaming with a concentrator' or 'VPN')
useVlanTaggingDirect trafic to use specific VLANs. This param is only valid with 'Bridge mode' and 'Layer 3 roaming'
concentratorNetworkIdThe concentrator to use for 'Layer 3 roaming with a concentrator' or 'VPN'.
vlanIdThe VLAN ID used for VLAN tagging. This param is only valid with 'Layer 3 roaming with a concentrator' and 'VPN'
defaultVlanIdThe default VLAN ID used for 'all other APs'. This param is only valid with 'Bridge mode' and 'Layer 3 roaming'
apTagsAndVlanIdsThe list of tags and VLAN IDs used for VLAN tagging. This param is only valid with 'Bridge mode', 'Layer 3 roaming'
tagsComma-separated list of AP tags
vlanIdNumerical identifier that is assigned to the VLAN
walledGardenEnabledAllow access to a configurable list of IP ranges, which users may access prior to sign-on.
walledGardenRangesSpecify your walled garden by entering space-separated addresses, ranges using CIDR notation, domain names, and domain wildcards (e.g. 192.168.1.1/24 192.168.37.10/32 www.yahoo.com *.google.com). Meraki's splash page is automatically included in your walled garden.
minBitrateThe minimum bitrate in Mbps. ('1', '2', '5.5', '6', '9', '11', '12', '18', '24', '36', '48' or '54')
bandSelectionThe client-serving radio frequencies. ('Dual band operation', '5 GHz band only' or 'Dual band operation with Band Steering')
perClientBandwidthLimitUpThe upload bandwidth limit in Kbps. (0 represents no limit.)
perClientBandwidthLimitDownThe download bandwidth limit in Kbps. (0 represents no limit.)
 

HEADERS


X-Cisco-Meraki-API-Key
{{X-Cisco-Meraki-API-Key}}
Content-Type
application/json

BODY


{
    "name": "viaPostman935",
    "enabled": false,
    "splashPage": "None",
    "perClientBandwidthLimitUp": 0,
    "perClientBandwidthLimitDown": 0,
    "ssidAdminAccessible": false,
    "ipAssignmentMode": "NAT mode",
    "authMode": "open"
}

 

Here are the docs for that endpoint:

https://documenter.getpostman.com/view/897512/meraki-dashboard-api/2To9xm?version=latest#712cd25d-f8...

Josh_14
Conversationalist

Thanks for the info. Appreciate it
BrechtSchamp
Kind of a big deal

You're welcome.

nealgs
Building a reputation

a bit late to the camp but I recently just finished a powershell script and implemented it last week:

 

It generates a random password (length and complexity can be changed in the script), it then updates the relevant SSID in the required site and emails the password to the reception mailbox.

 

Site name and SSID name are passed as parameters to the script.  Its currently used for just the guest wifi, but can obviously be used for any that uses a PSK.

 

It's scheduled to run at 4pm Fridays (this gives reception time to print out the new password ready for the nights and weekend security teams.

 

e.g.:

MerakiPSKTool.ps1 -site <sitename> -ssid <ssidname>

 

rgds

Gary

Ven
Here to help

This is exactly what I'm looking for.  SSID's psk must be changed once a month and the password emailed to a distro list.

Can you share your script?  I'm no good with power shell, but some folks here are.  I'm sure I could get them to help me implement.

 

thanks!

CMDRTucker
Here to help

Gary,

   Is your script available to share?  I am looking for something like this as well.  I am trying Splash Access now but I only want just that feature from them and not the whole package.  I don't think they price it separately.  There's automates the rotating of the PSK, but I believe I can only do one SSID.

Thanks,

   Steve

BrechtSchamp
Kind of a big deal

For those still looking to do this. I just wrote a script to do it. You can find it here:

https://community.meraki.com/t5/Wireless-LAN/Automatic-rotating-PSK-for-wireless/m-p/66028/highlight...

 

Ven
Here to help

Thanks BrechtSchamp!

I've just gotten started with Python, so this is a great script to use and learn!

I'm working on one that will run multiple remote commands on multiple Cisco wireless controllers. So far, it's very promising.

nealgs
Building a reputation

Hi Steve,

 

Below is the powershell script - As it stands, it is hard coded for a single organisation as the base URI contains the Org ID

 

You will just need to populate the necessary areas with your particular details etc.

 

I.E. smpt server and recipient info in function sendMail

API key in function Get-WifiSSID

base_uri & api_key in #setup some global static stuff section

email message body in section # build email message body and send it

 

You can change password length (currently 10 chars) and complexity by changing the code in function createPassword

 

 

 

 param([string]$site="",[string]$ssid="",[string]$action="")
  
 function sendMail([string]$txtbody)
	{
     #SMTP server name
     $smtpServer = "<InsertYourSMTPMailServerInfoHere>"

     #Creating a Mail object
     $msg = new-object Net.Mail.MailMessage

     #Creating SMTP server object
     $smtp = new-object Net.Mail.SmtpClient($smtpServer)

     #Email structure 
     $msg.From = "merakiapi@<YourMailDomainHere>"
     $msg.To.Add("<RecipientMailAddressHere>")
	 #$msg.To.Add("<OtherRecipientAddressHere")
     $msg.subject = "New password for guest Wifi" 
     $msg.body = $txtbody
	 $msg.IsBodyHTML=$true

     #Sending email 
     $smtp.Send($msg)
	}

function Get-RandomCharacters($length, $characters)
	{ 
    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length } 
    $private:ofs="" 
    return [String]$characters[$random]
	}

function Scramble-String([string]$inputString)
	{     
    $characterArray = $inputString.ToCharArray()   
    $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length     
    $outputString = -join $scrambledStringArray
    return $outputString 
	}

function updateWiFiPSK ([string]$s_id, [string]$w_id, [string]$newpassword)
	{
	[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

	# PSK = New password
	$data = @{
		"psk" = $newpassword
		}

	#Convert data to Json format
	$jbody = ConvertTo-Json -InputObject $data

	#Combine base URL and ssid
	$request_uri = $base_uri + $networks_uri + $s_id + "/ssids/" + $w_id
	
	$r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_org -Body $jbody

	return $r
	}
	
function Get-SiteID
    {
    #get site id
    $request_uri = $base_uri + $networks_uri
    $r = Invoke-WebRequest $request_uri -Method:Get -Headers $header_org

    $json = $r | ConvertFrom-Json
    for($i=0;$i -lt $json.count;$i++)
        {
        if ($site -eq $json[$i].name)
            {
            Write-host "Network Name : " $json[$i].name
            Write-host "id           : " $json[$i].id
            Write-host "Type         : " $json[$i].type

            $s_id = $json[$i].id
            }
        }

    return $s_id
    }

function Get-WiFiSSID ([string]$s_id)
    {
    #get wifi network ID from site requested
    if ($s_id -ne "")
        {
        $request_uri = $base_uri + $networks_uri + $s_id + "/ssids/"
        $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X-Cisco-Meraki-API-Key"="<ReplaceWithYouAPIKeyHere>"} -ContentType "application/json"

        $z = $r | ConvertFrom-Json

        for($i=0;$i -lt $z.count;$i++)
            {
          
            If ($z[$i].name -eq $ssid)
                {
                Write-host "SSID Name    : " $z[$i].name
                Write-host "SSID#        : " $z[$i].number 
                Write-host "Current PSK  : " $z[$i].psk

                $w_id = $z[$i].number
                }
            }
        }

    return $w_id
    }

function createPassword
	{
	$password = Get-RandomCharacters -length 4 -characters 'abcdefghiklmnoprstuvwxyz'
	$password += Get-RandomCharacters -length 2 -characters 'ABCDEFGHKLMNOPRSTUVWXYZ'
	$password += Get-RandomCharacters -length 2 -characters '1234567890'
	$password += Get-RandomCharacters -length 2 -characters '!$%&()?}][{@#+'	

	#Write-Host $password
		
	return Scramble-String $password
	}

# setup some global static stuff
$base_uri = "https://<InsertYourMerakiAPIBaseURLHere>"
##    E.G.   n34.meraki.com/api/v0/organizations/<OrgID>/
$networks_uri = "networks/"
#Meraki API KEY
$api_key = "<InsertYourAPIKeyHere>"
$header_org = @{"X-Cisco-Meraki-API-KEY" = $api_key;"Content-Type" = 'application/json'}

$s_id = ""
$w_id = ""
$mode = ""

If ($site -eq "" -or $ssid -eq "")
    {
    Write-Host "MerakiPSKTool - (c) 2019"
    Write-Host ""
    Write-Host "Site/SSID parameter is missing"
    Write-Host "Usage: MerakiPSKTool.ps1 -site <sitename> -ssid <ssidName> -action [Change | Display]"
    Write-Host ""
    
    exit
    } 

# if action not passed or is blank, set default mode to Display
if ($action -eq "")
    {
    $action = "Display"
    }

switch ($action)
    {
    {@("Display", "display") -contains $_ }
        {
            "Displaying Wifi details"
            $mode = "display"
        }
    
    {@("Change", "change") -contains $_ }
        {
            "Change Wifi password"
            $mode = "change"
        }

    default { "MerakiPSKTool.ps1" }
    }


# get ID of the site passed in params (set a default value if no site passed)
$s_id = Get-SiteID

If ($s_id -ne "")
    {
    # get id of Wifi network that password is to be changed for
    $w_id = Get-WifiSSID($s_id)

    #Write-Host "Site ID      : " $s_id " | Wifi #: " $w_id
    } 

if ($mode -eq "change")
    {
    # generate a new complex password
    $newpassword = createPassword 

    $result = updateWiFiPSK $s_id $w_id $newpassword

    #Write-Host $result

	# build email message body and send it
    if ($result.StatusCode -eq 200)
        {
        Write-Host "Sending Email"

        $txtbody = "<html><body>"
        $txtbody = $txtbody + "The new password for " + $ssid + " at " + $site + " is<br><br><b><font size=30 color=green>"
        $txtbody = $txtbody + $newpassword + "</font></b>"
        $txtbody = $txtbody + "<br><br>If you have any problems please contact <SomeContactDetailsHere>"
        $txtbody = $txtbody + "<br><br>regards<br>SignoffInfo"
        $txtbody = $txtbody + "</body></html>"

        #Write-Host $txtbody

		# send the email
        sendMail $txtbody
        }
    else
        {
        Write-Host "Password change failed for " + $ssid + " at " + $site
        }
    }

 

 

Copy and paste the above into text editor, make the necessary changes and save as MerakiPSKTool.ps1

 

to display current PSK for site, use

 

MerakiPSKTool.ps1 -site <sitename> -ssid <SSIDName> -action Display

 

to change psk for site use

 

MerakiPSKTool.ps1 -site <sitename> -ssid <SSIDName> -action Change

 

if no Action value provided it will default to Display

 

Current email body looks like this:

 

The new password for [ssidName] at [SiteName] is

z$ys$63mPX

If you have any problems please contact [ContactName] on [ContactTel] or [ContactEmail]

regards
[Contact]

 

Subject line is New password for guest Wifi

 

 

I'm not a pro programmer so use at own risk, i've had it running now for a good couple or months or so now and it's worked fine since.

 

rgds

Gary

 

CMDRTucker
Here to help

nealgs,

  THANK YOU for the reply.  I am getting an error that I think may be related to the base URL.  I am not sure where I find the orgid?  Can you give me a pointer on that please?

Thanks,

   Steve

nealgs
Building a reputation

hi Steve,

 

from your Meraki dashboard, type this url into address bar

 

https://dashboard.meraki.com/api/v0/organizations

 

or even just append your dashboard address to be

 

https://<yourdashboardurl>/api/v0/organizations

 

and press Enter - it should then return some json info:

 

 

 

[{"id":"<yourOrgID>".......

 

 

 

use the value in there for orgid - think it's a 6 digit number, at least ours is 

JoshMikow
Comes here often

Once the SSID password is changed, is there an easy way to tell it to sync across to other networks?

nealgs
Building a reputation

Hi JoshMikow,

 

As the code stands, no - it's per SSID in a named Network.  You'd have to run it once for each SSID in each network.  It would require a fair bit of change to do what you want.

 

I do have plans in the near future to amend it so that you can change the password for a named SSID across all networks - this is because we have a corporate wifi that we want to be able to sync passwords with to allow cross site visitors to be able to automatically access the Corporate Wifi once onsite - just waiting for the relevant infrastructure to be installed and setup to allow this (e.g. MR devices at those sites without)

 

I don't think there is a Meraki API call or anything in the Meraki Dashboard that will do what you need either.

 

rgds

Gary

JoshMikow
Comes here often

Thanks Gary. I'm also looking into using Configuration Templates to see if that would be a way to sync the settings. New to the API so I'm trying to make it as simple but secure as possible.

DavisJ
Here to help

Hello,

 

Thank you for the awesome script. I am just trying to run the script in display mode and all I see is 'Displaying Wifi details' but nothing after that, any ideas?

 

Thanks,

 

Davis

nealgs
Building a reputation

Hi Davis,

 

Make sure you have the correct specific info in place - e.g. network id, API key etc

 

rgds

Gary

 

 

DavisJ
Here to help

Hi Gary,

 

Thank you for your quick response - where in your code should I include the network ID? Sorry, I tried to find it but I couldn't.

 

I have updated the API key.


Thanks,

Davis

 

nealgs
Building a reputation

Hi Davis,

 

In the original posting the changes you need to make are

 

smpt server and recipient info in function sendMail

API key in function Get-WifiSSID

base_uri & api_key in #setup some global static stuff section

email message body in section # build email message body and send it

 

If you search for the text bolded above, that will take you to the relevant areas you need to modify with your info

in the code

 

give me a shout if any more help needed 🙂

DavisJ
Here to help

Yes, I have done those (above mentioned) changes already except for updating the 'network ID' and I couldn't tell where to include this info. What am I missing?

 

Thank you,

Davis

 

 

 

DavisJ
Here to help

My bad, I was missing the '/' at the end of $base_uri and I can get the output finally using the 'Display'.

 

I will try to use the 'Change' as well as do further testing and get back if I need any help.

 

Thank you for your assistance, much appreciated.

nealgs
Building a reputation

Good to hear you got it sorted 🙂

 

No problem - drop a post in here if any more issues.

 

 

Taslim
Comes here often

HI Nealgs

 

I am not getting clear about update Get-WifiSSID value in script, please help on this

nealgs
Building a reputation

Hi Taslim,

 

You need to apply for an API access code the value of which goes into the Get-WifiSSID function

 

Go to Organisation/Settings and scroll down to bottom.  You should see a section called

 

Dashboard API Access

 

tick Enable access too ..... and following instructions to get you API key

 

This key then goes into the code sections Get-WifiSSID function and the setup some globals section

 

rgds

Gary

Taslim
Comes here often

Hi Neagls,

 

First of all thanks to your all help.

 

I have set the API key and i am able to communicate the API, i tested through https://developer.cisco.com/meraki/api-v1/#!update-network-wireless-ssid.

 

 

error.pngHardcorded.pngnooutput.png

nealgs
Building a reputation

Hi Taslim,

 

The first error message (red text on blue) usually occurs if you don't provide the full path to a Ps1 script.

 

So for example, my merakipsktool.ps1 file resides in
C:\tst\powershell

 

if i'm in Powershell ISE, then i'd CD to c:\tst\powershell

and to run the script, i'd type

 

.\merakipsktool.ps1

 

this displays the the copyright sign and a message that the site/ssid parameter was missed

 

The 2nd screen where yours appears to show nothing i'd say is due to something not being entered correctly in the areas of the script that need to be changed to have your Meraki specific details.

 

Can you double check them again, and make sure you include a '/' at the end of $base_uri variable - (see DavisJ post earlier)

 

rgds

Gary

Taslim
Comes here often

Hi Nealgs,

 

Yaa i was missing / at the end of Base Uri, Now Display action working perfectly, however change action not working getting below error.

 

PS C:\Users\test\desktop> .\merakipsktool.ps1
Change Wifi password
Network Name :  Name of network
id           :  N_XXXXXX
Type         :  wireless
SSID Name    :  SSID Name
SSID#        :  0
Current PSK  :  Nn!v5Gz)DHkvp=
 
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At C:\Users\test\desktop\MerakiPSKTool.ps1:55 char:7
+     $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_org -Body $jbo ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
   eption
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
Password change failed for  + SSID Name +  at  + Name of Network
PS C:\Users\test\desktop>
Taslim
Comes here often

 

 

 

 

param([string]$site=" changed according to us ",[string]$ssid="changed according to us",[string]$action="Display")

 

 function sendMail([string]$txtbody)

              {

     #SMTP server name

     $smtpServer = " changed according to us "

 

     #Creating a Mail object

     $msg = new-object Net.Mail.MailMessage

 

     #Creating SMTP server object

     $smtp = new-object Net.Mail.SmtpClient($smtpServer)

 

     #Email structure

     $msg.From = "merakiapi@ changed according to us "

     $msg.To.Add("changed according to us ")

                   $msg.subject = "New password for guest Wifi"

     $msg.body = $txtbody

               $msg.IsBodyHTML=$true

 

     #Sending email

     $smtp.Send($msg)

              }

 

function Get-RandomCharacters($length, $characters)

              {

    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length }

    $private:ofs=""

    return [String]$characters[$random]

              }

 

function Scramble-String([string]$inputString)

              {    

    $characterArray = $inputString.ToCharArray()   

    $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length    

    $outputString = -join $scrambledStringArray

    return $outputString

              }

 

function updateWiFiPSK ([string]$s_id, [string]$w_id, [string]$newpassword)

              {

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

 

              # PSK = New password

              $data = @{

                             "psk" = $newpassword

                             }

 

              #Convert data to Json format

              $jbody = ConvertTo-Json -InputObject $data

 

              #Combine base URL and ssid

              $request_uri = $base_uri + $networks_uri + $s_id + "/ssids/" + $w_id

             

              $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_org -Body $jbody

 

              return $r

              }

             

function Get-SiteID

    {

    #get site id

    $request_uri = $base_uri + $networks_uri

    $r = Invoke-WebRequest $request_uri -Method:Get -Headers $header_org

 

    $json = $r | ConvertFrom-Json

    for($i=0;$i -lt $json.count;$i++)

        {

        if ($site -eq $json[$i].name)

            {

            Write-host "Network Name : " $json[$i].name

            Write-host "id           : " $json[$i].id

            Write-host "Type         : " $json[$i].type

 

            $s_id = $json[$i].id

            }

        }

 

    return $s_id

    }

 

function Get-WiFiSSID ([string]$s_id)

    {

    #get wifi network ID from site requested

    if ($s_id -ne "")

        {

        $request_uri = $base_uri + $networks_uri + $s_id + "/ssids/"

        $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X-Cisco-Meraki-API-Key"=" changed according to us "} -ContentType "application/json"

 

        $z = $r | ConvertFrom-Json

 

        for($i=0;$i -lt $z.count;$i++)

            {

         

            If ($z[$i].name -eq $ssid)

                {

                Write-host "SSID Name    : " $z[$i].name

                Write-host "SSID#        : " $z[$i].number

                Write-host "Current PSK  : " $z[$i].psk

 

                $w_id = $z[$i].number

                }

            }

        }

 

    return $w_id

    }

 

function createPassword

              {

              $password = Get-RandomCharacters -length 4 -characters 'abcdefghiklmnoprstuvwxyz'

              $password += Get-RandomCharacters -length 2 -characters 'ABCDEFGHKLMNOPRSTUVWXYZ'

              $password += Get-RandomCharacters -length 2 -characters '1234567890'

              $password += Get-RandomCharacters -length 2 -characters '!$%&()?}][{@#+'     

 

              #Write-Host $password

                            

              return Scramble-String $password

              }

 

# setup some global static stuff

$base_uri = "https://nXX.meraki.com/api/v0/organizations/ changed according to us/ "

##    E.G.   n34.meraki.com/api/v0/organizations/<OrgID>/

$networks_uri = "networks/"

#Meraki API KEY

$api_key = " changed according to us "

$header_org = @{"X-Cisco-Meraki-API-KEY" = $api_key;"Content-Type" = 'application/json'}

 

$s_id = ""

$w_id = ""

$mode = ""

 

If ($site -eq "" -or $ssid -eq "")

    {

    Write-Host "MerakiPSKTool - (c) 2019"

    Write-Host ""

    Write-Host "Site/SSID parameter is missing"

    Write-Host "Usage: MerakiPSKTool.ps1 -site changed according to us -ssid changed according to us -action [Change | Display]"

    Write-Host ""

   

    exit

    }

 

# if action not passed or is blank, set default mode to Display

if ($action -eq "")

    {

    $action = "Display"

    }

 

switch ($action)

    {

    {@("Display", "display") -contains $_ }

        {

            "Displaying Wifi details"

            $mode = "display"

        }

   

    {@("Change", "change") -contains $_ }

        {

            "Change Wifi password"

            $mode = "change"

        }

 

    default { "MerakiPSKTool.ps1" }

    }

 

 

# get ID of the site passed in params (set a default value if no site passed)

$s_id = Get-SiteID

 

If ($s_id -ne "")

    {

    # get id of Wifi network that password is to be changed for

    $w_id = Get-WifiSSID($s_id)

 

    #Write-Host "Site ID      : " $s_id " | Wifi #: " $w_id

    }

 

if ($mode -eq "change")

    {

    # generate a new complex password

    $newpassword = createPassword

 

    $result = updateWiFiPSK $s_id $w_id $newpassword

 

    #Write-Host $result

 

              # build email message body and send it

    if ($result.StatusCode -eq 200)

        {

        Write-Host "Sending Email"

 

        $txtbody = "<html><body>"

        $txtbody = $txtbody + "The new password for " + $ssid + " at " + $site + " is<br><br><b><font size=30 color=green>"

        $txtbody = $txtbody + $newpassword + "</font></b>"

        $txtbody = $txtbody + "<br><br>If you have any problems please contact <SomeContactDetailsHere>"

        $txtbody = $txtbody + "<br><br>regards<br>SignoffInfo"

        $txtbody = $txtbody + "</body></html>"

 

        #Write-Host $txtbody

 

                             # send the email

        sendMail $txtbody

        }

    else

        {

        Write-Host "Password change failed for " + $ssid + " at " + $site

        }

    }

Taslim
Comes here often

Hi Gary,

 

 
Change Output
=================================
Change Wifi password
Network Name :  XXXXXX
id           :  N_XXXXXX
Type         :  wireless
SSID Name    :  XXXXX
SSID#        :  1
Current PSK  :  k7fB37!oER#t$N
New Password :  W$)c7uss4W
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At C:\Users\Test\Desktop\MerakiPSKTool.ps1:55 char:7
+     $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_org -Body $jbo ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebReques 
   t], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCo 
   mmand
 
Password change failed for  + XXXXX +  at  + XXXXXX
 
Display output
==============================
Displaying Wifi details
Network Name :  XXXX
id           :  N_XXXX
Type         :  wireless
SSID Name    :  XXXX
SSID#        :  1
Current PSK  :  k7fB37!oER#t$N
 
Taslim
Comes here often

 

 

All good now its working as expected.

Thanks lots

Taslim
Comes here often

Hi Gary,

 

Is there any script available to change the PSK if site network managed by configuration template, i tried with couple of change but not working.

nealgs
Building a reputation

Hi Taslim

 

Sorry can't help on that one im afraid - not really used config templates, so not sure how they differ with regards to directly changing a SSID psk.

 

rgds

Gary

nealgs
Building a reputation

Hi Taslim,

 

Good to hear 🙂

 

What was the problem in the end - would be good to know in case someone else has similar issues.

 

rgds

Gary

Taslim
Comes here often

 

Getting Below error, Please help.

 

+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (MerakiPSKTool.ps1:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

nealgs
Building a reputation

Hi Taslim

 

Can you provide a screenshot of how you are attempting to run the script - the error seems to be incomplete as it's not saying which Command isn't found.

 

I've not seen that error during my testing and final implementation of the script.

 

rgds

Gary

Jason7
Here to help

Great script, thanks.

 

Using the script as is I got the below error due to TLS issues.

 

The underlying connection was closed: An unexpected error occurred on a send.

 

Adding the below line before invoking the web request did the trick.

 

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

nealgs
Building a reputation

Hi Jason7,

 

I've never seen that error before 🙂 very strange.  I've had the script running for over a year now.  Executes a scheduled task at 4pm every Friday to change the guest wifi password and sends out and email to a couple of recipients with the new one.

 

The line you entered already exists in the function updateWiFiPSK

 

rgds

Gary

 

Jason7
Here to help

I added the line prior to the web request in the Get-SiteID function. It may be something specific in relation to my host. Either way it is working well now and running as a scheduled task. Thanks for sharing, saved me hours 🙂

John_W8
Comes here often

Hi Nealgs,
For the life of me I can't get the script to work. I have made sure everything is good and even tested my URL links outside of the script and can get to them, but I keep getting a blank readout when trying to display and when I try to run change I get a 404 error

STM
Comes here often

I have got following error message when I try with "Change" option. "Display" option is okay. Can help me check this error?

 

Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At C:\Users\sithu\Dropbox\AMNET\Meraki WiFi PSK Auto Generate\MerakiPSKTool.ps1:56 char:7
+ $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

nealgs
Building a reputation

Hi STM,

 

Can you confirm you have made all of the necessary changes in the script to contain your meraki details

 

i.e the values for $request_uri, $header_org and $jbody etc have been set correctly

 

Gary

 

 

STM
Comes here often

Hi Nealgs,

 

Yes, I made necessary changes in script. I can see the SSID PSK with "Display" switch. But I cannot change the PSK. If I run with "Change" switch, this error occurs.

 

Following is my Script that I add required parameters.

 

 

 param([string]$site="",[string]$ssid="",[string]$action="")
  
 function sendMail([string]$txtbody)
{
     #SMTP server name
     $smtpServer = "xxx.xxx.xxx.xxx"
 
     #Creating a Mail object
     $msg = new-object Net.Mail.MailMessage
 
     #Creating SMTP server object
     $smtp = new-object Net.Mail.SmtpClient($smtpServer)
 
     #Email structure 
     $msg.From = "merakiapi@xxx.com"
     $msg.To.Add("xxx@xxx.com")
#$msg.To.Add("<OtherRecipientAddressHere")
     $msg.subject = "New password for guest Wifi" 
     $msg.body = $txtbody
$msg.IsBodyHTML=$true
 
     #Sending email 
     $smtp.Send($msg)
}
 
function Get-RandomCharacters($length, $characters)
    $random = 1..$length | ForEach-Object { Get-Random -Maximum $characters.length } 
    $private:ofs="" 
    return [String]$characters[$random]
}
 
function Scramble-String([string]$inputString)
{     
    $characterArray = $inputString.ToCharArray()   
    $scrambledStringArray = $characterArray | Get-Random -Count $characterArray.Length     
    $outputString = -join $scrambledStringArray
    return $outputString 
}
 
function updateWiFiPSK ([string]$s_id, [string]$w_id, [String]$newpassword)
{
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
 
# PSK = New password
$data = @{
        "encryptionMode" = "wpa"
        "authMode" = "psk"
"psk" = $newpassword
}
 
#Convert data to Json format
$jbody = ConvertTo-Json -InputObject $data
 
#Combine base URL and ssid
$request_uri = $base_uri + $networks_uri + $s_id + "/ssids/" + $w_id
 
$r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_org -Body $jbody
 
return $r
}
 
function Get-SiteID
    {
    #get site id
    $request_uri = $base_uri + $networks_uri
    $r = Invoke-WebRequest $request_uri -Method:Get -Headers $header_org
 
    $json = $r | ConvertFrom-Json
    for($i=0;$i -lt $json.count;$i++)
        {
        if ($site -eq $json[$i].name)
            {
            Write-host "Network Name : " $json[$i].name
            Write-host "id           : " $json[$i].id
            Write-host "Type         : " $json[$i].type
 
            $s_id = $json[$i].id
            }
        }
 
    return $s_id
    }
 
function Get-WiFiSSID ([string]$s_id)
    {
    #get wifi network ID from site requested
    if ($s_id -ne "")
        {
        $request_uri = $base_uri + $networks_uri + $s_id + "/ssids/"
        $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X-Cisco-Meraki-API-Key"="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"} -ContentType "application/json"
 
        $z = $r | ConvertFrom-Json
 
        for($i=0;$i -lt $z.count;$i++)
            {
          
            If ($z[$i].name -eq $ssid)
                {
                Write-host "SSID Name    : " $z[$i].name
                Write-host "SSID#        : " $z[$i].number 
                Write-host "Current PSK  : " $z[$i].psk
 
                $w_id = $z[$i].number
                }
            }
        }
 
    return $w_id
    }
 
function createPassword
{
$password = Get-RandomCharacters -length 4 -characters 'abcdefghiklmnoprstuvwxyz'
$password += Get-RandomCharacters -length 2 -characters 'ABCDEFGHKLMNOPRSTUVWXYZ'
$password += Get-RandomCharacters -length 2 -characters '1234567890'
$password += Get-RandomCharacters -length 2 -characters '!$%&()?}][{@#+'
 
#Write-Host $password
 
return Scramble-String $password
}
 
# setup some global static stuff
##    E.G.   n34.meraki.com/api/v0/organizations/<OrgID>/
$networks_uri = "networks/"
#Meraki API KEY
$api_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$header_org = @{"X-Cisco-Meraki-API-KEY" = $api_key;"Content-Type" = 'application/json'}
 
$s_id = ""
$w_id = ""
$mode = ""
 
If ($site -eq "" -or $ssid -eq "")
    {
    Write-Host "MerakiPSKTool - (c) 2019"
    Write-Host ""
    Write-Host "Site/SSID parameter is missing"
    Write-Host "Usage: MerakiPSKTool.ps1 -site <sitename> -ssid <ssidName> -action [Change | Display]"
    Write-Host ""
    
    exit
    } 
 
# if action not passed or is blank, set default mode to Display
if ($action -eq "")
    {
    $action = "Display"
    }
 
switch ($action)
    {
    {@("Display", "display") -contains $_ }
        {
            "Displaying Wifi details"
            $mode = "display"
        }
    
    {@("Change", "change") -contains $_ }
        {
            "Change Wifi password"
            $mode = "change"
        }
 
    default { "MerakiPSKTool.ps1" }
    }
 
 
# get ID of the site passed in params (set a default value if no site passed)
$s_id = Get-SiteID
 
If ($s_id -ne "")
    {
    # get id of Wifi network that password is to be changed for
    $w_id = Get-WifiSSID($s_id)
 
    #Write-Host "Site ID      : " $s_id " | Wifi #: " $w_id
    } 
 
if ($mode -eq "change")
    {
    # generate a new complex password
    $newpassword = createPassword 
 
    $result = updateWiFiPSK $s_id $w_id $newpassword
 
    #Write-Host $result
 
# build email message body and send it
    if ($result.StatusCode -eq 200)
        {
        Write-Host "Sending Email"
 
        $txtbody = "<html><body>"
        $txtbody = $txtbody + "The new password for " + $ssid + " at " + $site + " is<br><br><b><font size=30 color=green>"
        $txtbody = $txtbody + $newpassword + "</font></b>"
        $txtbody = $txtbody + "<br><br>If you have any problems please contact XXX"
        $txtbody = $txtbody + "<br><br>regards<br>SignoffInfo"
        $txtbody = $txtbody + "</body></html>"
 
        #Write-Host $txtbody
 
# send the email
        sendMail $txtbody
        }
    else
        {
        Write-Host "Password change failed for " + $ssid + " at " + $site
        }
    }
 
 
Thanks a lot for your reply.
 
Regards,
nealgs
Building a reputation

I've never tried the code changing or adding anything more than just the password value.

 

Can you try it but remove the entries in the $data section so it looks like this:

 

$data = @{
 "psk" = $newpassword
}
 

I'd suggest installing Postman app and getting the Meraki API collection - it allows you to mess around with calls etc and see the results. 

 

 
regards
Gary
nealgs
Building a reputation

for multiple values in $data i think they need to be separated by commas

 

$data = @{
        "encryptionMode" = "wpa",
        "authMode" = "psk",
"psk" = $newpassword
}
STM
Comes here often

Hi nealgs,
   
If I add comma and run the script, it got following issue.
 
 
At C:\Users\sithu\Desktop\MerakiPSKTool.ps1:47 char:28
+ "encryptionMode" = "wpa",
+ ~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
At C:\Users\sithu\Desktop\MerakiPSKTool.ps1:48 char:9
+ "authMode" = "psk",
+ ~~~~~~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
At C:\Users\sithu\Desktop\MerakiPSKTool.ps1:48 char:22
+ "authMode" = "psk",
+ ~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
At C:\Users\sithu\Desktop\MerakiPSKTool.ps1:49 char:3
+ "psk" = $newpassword
+ ~~~~~
The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidLeftHandSide
 
 
 
 
If I don't add this two parameters "encryptionMode=wpa, authMode=psk", I got following issue when I run the script with "change" switch.
 
 
Invoke-WebRequest : The remote server returned an error: (400) Bad Request.
At C:\Users\sithu\Desktop\MerakiPSKTool.ps1:56 char:7
+     $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_ ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
 
 
Thank you.
nealgs
Building a reputation

Hi STM,

 

Ok, i've just tried the script out changing multiple values

 

$data = @{

    "authMode" = "psk"

    "encryptionMode" = "wpa"

    "psk" = $newpassword"

    }

 

I tried with commas and it generated the errors - remove commas and it runs and changes the password ok.

 

Not sure why you want to include/change authmode and encryptionmode as i'd thought they would stay the same each time?

 

Gary

 

 

 

STM
Comes here often

Hi nealgs,

 

I also tried and get the new PSK from email. But when I check the SSID PSK on Meraki dashboard, it display old PSK.

 

It should display the updated PSK, right?

 

 

Regards,

nealgs
Building a reputation

Add the following line in green (code is around line 184) into the script - this will display the new password as well

 

if ($mode -eq "change")
    {
    # generate a new complex password
    $newpassword = createPassword
 
Write-Host "New Password : " $newpassword
 
    $result = updateWiFiPSK $s_id $w_id $newpassword
 
    #Write-Host $result

 

it'll can take a couple of mins for the Meraki portal to show the changed password - but if you run the script again in display mode, it should show the new password as the Current password.

 

run script in display mode gets this output:

Network Name : <nameofnetwork>
id : <blahblah>
Type : combined
SSID Name : APITest
SSID# : 5
Current PSK : TkGl55[&51

 

run in change mode should show the output below after you put in the extra line in the script:

Change Wifi password
Network Name : <nameofnetwork>
id : <blahblah>
Type : combined
SSID Name : APITest
SSID# : 5
Current PSK : TkGl55[&51
New Password : 8$1vA9p4T[
Sending Email

 

Paste your results in here once run

 

Gary

STM
Comes here often

Hi nealgs,

 

This is output of "change".

 

Change Wifi password
Network Name : STM-HQ
id : N_739153288842186759
Type : wireless
SSID Name : GUEST_WIFI
SSID# : 1
Current PSK : 73gbL#!Bym

New PSK : pWD%3hc4a$

Sending Email

 

 

This is output of "display". It shows updated password.

 

Displaying Wifi details
Network Name : STM-HQ
id : N_739153288842186759
Type : wireless
SSID Name : GUEST_WIFI
SSID# : 1
Current PSK : pWD%3hc4a$

 

 

For SSID PSK in Meraki dashboard, it still shows very old one.

But we don't need to take note that PSK right?

nealgs
Building a reputation

looking at the output, the psk is being changed correctly

 

the display mode lists the current psk password it get it's from the ssid you provide so it is reading correct one and looks to be working ok.

 

I don't quite understand your line:

 

For SSID PSK in Meraki dashboard, it still shows very old one.

 

for the display mode to show the correct value, then the value in the Meraki Dashboard must also be correct as they both read the value from the same location (i assume).

 

Gary

Paul1226
Conversationalist

Having an issue I am not sure how to resolve. This is the error

 

PS C:\Meraki Scripts> .\MerakiPSKTool.ps1 -site Wireless -ssid Guest
Displaying Wifi details
Network Name : Wireless
id : N_616000344304523008
Type :
Invoke-WebRequest : Page not found
The page you are looking for may have been moved or does not exist.
To log in to the Cisco Meraki Dashboard, go to https://dashboard.meraki.com.© 2021 Cisco Systems, Inc.
At C:\Meraki Scripts\MerakiPSKTool.ps1:138 char:14
+ ... $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X- ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At C:\Meraki Scripts\MerakiPSKTool.ps1:140 char:19
+ $z = $r | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand

 

 

nealgs
Building a reputation

Hi Paul1226,

 

Hmm, strange one is this.

 

It looks to of failed in the Get-WifiSSID function which is called once it gets the site ID ($s_id) from the Get-SiteID function.

 

Are you sure that the Network you are querying has any wireless devices on it?

 

If i run the scripts against a site without any wifi devices i get an Invoke-WebRequest error at the same point.

 

Paul1226
Conversationalist

discovered this issue in my base uri was using v1 and v0

 

failed with this code

   # setup some global static stuff
   $base_uri = "https://api.meraki.com/api/v1/organizations/<OrgID>/"

functioned properly using this code

   # setup some global static stuff

   $base_uri = "https://api.meraki.com/api/v0/organizations/<OrgID>/"

nealgs
Building a reputation

Great news 🙂

 

The original post with the script code does mention to make sure the Base URI is correct for your site.  It would appear the there are other possibilities for the vX value based on this v0 and v1.

 

i'll add a note into original post for this.

 

rgds

Gary

Tommy3268
New here

Hi, 

 

I am running the change command with your script and am getting:

 

Invoke-WebRequest : The remote server returned an error: (404) Not Found.
At C:\MerakiPSKTool.ps1:56 char:7
+ $r = Invoke-WebRequest $request_uri -Method:Put -Headers $header_ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

 

I am pretty sure everything is correct. Any ideas why I might be seeing this? 

 

Thanks! 

DillonofAnch17
Getting noticed

great question!
AshokS
Comes here often

Can you someone help me, how to change the authentication : " enabled" : false "for view the password XXXX and modify 

{
    "localStatusPageEnabled"true,
    "remoteStatusPageEnabled"false,
    "securePort": {
        "enabled"false
    },
    "localStatusPage": {
        "authentication": {
            "enabled"true,
            "username""admin"
        }
    }
}
PrashantNagaraj
Just browsing

Hello
 
Thanks for the excellent script. However it is erroring out when I run as :
> .\MerakiPSKTool.ps1 -site "MySiteName" -ssid "MySSIDName" -action Display
 
The error is :
===
Displaying Wifi details
Invoke-WebRequest : Page not found
The page you are looking for may have been moved or does not exist.
To log in to the Cisco Meraki Dashboard, go to https://dashboard.meraki.com.© 2024 Cisco Systems, Inc.
At \PATH\TO\\MerakiPSKTool.ps1:66 char:10
+     $r = Invoke-WebRequest $request_uri -Method:Get -Headers $header_ ...
+          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At \PATH\TO\\MerakiPSKTool.ps1:68 char:18
+     $json = $r | ConvertFrom-Json
+                  ~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
===
 
I have modified the script for specific that need to replaced as per my ORG_ID, API _Key as :
 
===
function Get-WiFiSSID ([string]$s_id)
    {
    #get wifi network ID from site requested
    if ($s_id -ne "")
        {
        $request_uri = $base_uri + $networks_uri + $s_id + "/ssids/"
        $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X-Cisco-Meraki-API-Key"="API_Key"} -ContentType "application/json"
 
# setup some global static stuff
##    E.G.   n34.meraki.com/api/v0/organizations/<OrgID>/
$networks_uri = "networks/"
#Meraki API KEY
$api_key = "API_Key"
===
 
For the $base_uri, I have tried with 
 
All the above result in the same error
 
Can you please guide me how to solve this ?
PhilipDAth
Kind of a big deal
Kind of a big deal

Looking at that code, it should be:
$base_uri = "https://api.meraki.com/api/v1/organizations/ORG_ID/"

PrashantNagaraj
Just browsing

I have already tried the below and still the error is same. The URL's I have tried are 

 

"https://api.meraki.com/api/v0/organizations/ORG_ID/"
"https://api.meraki.com/api/v1/organizations/ORG_ID/"

"https://n290.meraki.com/api/v0/organizations/ORG_ID/>"
"https://n290.meraki.com/api/v1/organizations/ORG_ID/>"

"https://dashboard.meraki.com/api/v0/organizations/ORG_ID/"
"https://dashboard.meraki.com/api/v1/organizations/ORG_ID/"

 

All of them fail with the same error, I have made double confirmation that API_Key works. Also replaced the ORG_ID with the ORG_ID displayed in most of the web_pages at the bottom "Data for XYZ (organization ID: 123456) is hosted in Asia-Pacific"

PhilipDAth
Kind of a big deal
Kind of a big deal

Try:
"https://api.meraki.com/api/v1/organizations/ORG_ID/"

 

And then give us the new error.  It will be a different error.

PrashantNagaraj
Just browsing

With the $base_uri = "https://api.meraki.com/api/v1/organizations/12345/" - 12345 being the org_id displayed at the bottom of my meraki dashboard page in Web_UI , I run the command as
.\MerakiPSKTool.ps1 -site <sitename> -ssid <ssidName> -action Display

The errors are :
===
Displaying Wifi details
Network Name : NetworkName
id : Network_Id
Type :
Invoke-WebRequest : Page not found
The page you are looking for may have been moved or does not exist.
To log in to the Cisco Meraki Dashboard, go to https://dashboard.meraki.com.© 2024 Cisco Systems, Inc.
At D:\scripts\amagi\MerakiPSKTool.ps1:90 char:14
+ ... $r = Invoke-WebRequest $request_uri -Method:Get -Headers @{"X- ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
ConvertFrom-Json : Cannot bind argument to parameter 'InputObject' because it is null.
At D:\scripts\amagi\MerakiPSKTool.ps1:92 char:19
+ $z = $r | ConvertFrom-Json
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [ConvertFrom-Json], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
===

Jason7
Here to help

This script stopped working for us (with the same error) some time back. We never did get the time to troubleshoot and update. v0 of the dashboard API is now sunset and you'll need to update to work with v1. If you do get it working let us know what you needed to amend. Sorry I cannot give you the answer. Best of luck.