jim edgar
jim edgar

Reputation: 31

Why is the external IP not returned from a UPnP GetExternalIPAddress query using powershell/COM?

I am trying to use powershell to query/control UPnP devices.

I researched and came up with using the UPnP.UPnPDeviceFinder object to get the list of upnp devices. Now as a first step to learn how to control a upnp device with powershell I want to get the external address of the router using the upnp WANConnectionDevice that my router contains.
The closest example I could find was for VBScript at https://msdn.microsoft.com/en-us/library/windows/desktop/aa381230(v=vs.85).aspx Note the goal is to understand how to control upnp devices this way - there are better ways I know of to get the external IP.

get all the UPnP devices

$finder = New-Object -ComObject UPnP.UPnPDeviceFinder
$devices = $finder.FindByType("upnp:rootdevice", 0)

from my earlier experimenting I know the UPnP WANConnectionDevice is the grandchild of the router COM object

$router = $devices | where friendlyname -eq RT-N66U
$routerchild = $router | % {$_.Children}   # simple $router.Children syntax does not work, methods and properties are not available.
$routergrandchild = $routerchild | % {$_.Children}

this shows $routergrandchild is the WANConnectionDevice

$routergrandchild.FriendlyName

WANConnectionDevice

get the services object from this

$wanconnectservice = $routergrandchild | % {$_.services}

examine the invokeaction method

$wanconnectservice | gm -MemberType Method invokeaction

TypeName: System.__ComObject#{a295019c-dc65-47dd-90dc-7fe918a1ab44}

Name MemberType Definition
---- ---------- ----------
InvokeAction Method Variant InvokeAction (string, Variant, Variant)

From the get-member signature above and from my earlier experimenting I know the GetExternalIPAddress action has only 1 output arg and no input args. So pass an empty array for input and for the 1 output arg pass a [ref]

$xip = @()
$wanconnectservice.InvokeAction('GetExternalIPAddress', @(), [ref]$xip)

The result of this is a request is sent to the router and it responds correctly with the externalip (confirmed by wireshark) I would also expect an S_OK to be returned and have $xip contain the externalip string. What I get is no response (no errors either) and $xip is unchanged. I tried setting $xip = @('') and got the same result.

Is my syntax wrong or are my expectations wrong? Maybe because the external IP has not changed I get nothing in $xip?

Note that

$wanconnectservice.QueryStateVariable('ExternalIPAddress')

does return the current address - but this is cached. There is no wireshark activity since ExternalIPAddress is an evented variable as noted in the documentation at: https://msdn.microsoft.com/en-us/library/windows/desktop/aa382244(v=vs.85).aspx

Upvotes: 0

Views: 1223

Answers (1)

jim edgar
jim edgar

Reputation: 31

Well, I am embarrassed to publish this but the solution is very simple:

$xip = **$null**
$wanconnectservice.InvokeAction('GetExternalIPAddress', @(), [ref]$xip)
$xip

Upvotes: 3

Related Questions