17 Replies Latest reply on Nov 8, 2017 4:01 PM by tomiannelli

    Invoke-SwisVerb Access Denied

    erwabo

      We are on IPAM 4.5

       

      I have everything set up according to the TWACK documentation but none of the IP Address Cmdlets are letting me perform actions, however THIS does work

       

       

      Get-SwisData $swis 'SELECT TOP 1 I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24'''

       

      But I dont know all the SQL commands to perform all the tasks that you can with the cmdlets.

       

      When I try the Invoke-SwisVerb with the same account I get:

       

      Invoke-SwisVerb : Access denied

      En D:\PowerShell\orion_ipam.ps1: 25 Carácter: 1

      + Invoke-SwisVerb $swis IPAM.SubnetManagement GetFirstAvailableIp @("10 ...

      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          + CategoryInfo          : InvalidOperation: (:) [Invoke-SwisVerb], FaultException`1

          + FullyQualifiedErrorId : SwisError,SwisPowerShell.InvokeSwisVerb

       

      I saw this on another post too, but it was older and no remedy to the issue. Is this a  bug? Has it been resolved? OR are there equivalent queries I can run to replicated the functions of the IPAM.SubnetManagement method.

       

      Thanks!

        • Re: Invoke-SwisVerb Access Denied
          bobmarley

          You need to authenticate first. Try using this command to authenticate before using other commands.

           

          Add-PSSnapin SwisSnapin

          $swis = Connect-Swis -host YOURORIONSERVERNAME -Trusted

          • Re: Invoke-SwisVerb Access Denied
            tomiannelli

            Interesting. That output looks like you get an XML element returned. Which is what you expect from the Invoke-SwisVerb PowerShell · solarwinds/OrionSDK Wiki · GitHub

            I ran the same script using Get-SWISDATA and get a string back.

            Import-Module SwisPowerShell

            Add-PSSnapin SwisSnapin

            $swis = Connect-Swis -host <myhost name> -Trusted

            $IP= Get-SwisData $swis 'SELECT TOP 1 I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''Muscatine Datacenter'''

            PS> Get-Member -InputObject $IP

            TypeName: System.String

            PS> $IP

            10.1.190.54

             

            I run this from my PC and connect to my SolarWinds primary poller. What does your Invoke-SwisVerb command look like?

              • Re: Invoke-SwisVerb Access Denied
                erwabo

                Yes if I use SWQL commands I do get a string....however my goal is to perform the following

                 

                1. Get the next available IP (within a range like between 10.10.10.30 and 10.10.10.230)

                2. Set it to USED

                3. Write The Hostname

                 

                All that can be done with the cmdlets (https://github.com/solarwinds/OrionSDK/wiki/IPAM-API)

                 

                My understanding is that SWQL only reads command, you have to use the Invoke commands or CRUD to write

                  • Re: Invoke-SwisVerb Access Denied
                    tomiannelli

                    Add-PSSnapin SwisSnapin

                    $swis = Connect-Swis -host fooweb.foobar.com -Trusted

                    $result = Invoke-SwisVerb -SwisConnection $Swis -EntityName IPAM.SubnetManagement -Verb GetFirstAvailableIp -Arguments @("10.1.190.0", "23")

                    $IP = $result.Innertext

                    # WANT TO GET THE NODEID

                    $Select = "SELECT I.IPNodeID,I.IPAddress FROM IPAM.IPNode I WHERE I.IPAddress = '" + $IP + "'"

                    $R2 = Get-SwisData $swis $Select

                    $R2 | FT

                    Invoke-SwisVerb $swis IPAM.SubnetManagement ChangeIPStatus  @($IP, "Used")

                    $URI = 'swis://fooweb.foobar.com/Orion/IPAM.IPNode/IpNodeId=' + $R2.IPNodeID

                    # Change the property you want I just used Alias because it was easy

                    Set-SwisObject $swis -Uri $URI -Properties @{ Alias = 'Reset Me' }

                      • Re: Invoke-SwisVerb Access Denied
                        erwabo

                        sorry...I meant get the first available IP ONLY within that range. They dont want us to use anything below .30 or above .230. Is that possible. I can have them set those to reserved in IPAM, but that would not be preferred if possible

                         

                        Also that last line in that script returns this for me even if I use Alias or any other of the listed properties:

                         

                        Set-SwisObject : Entity IPAM.IPNode does not contain requested property HOSTNAME

                        At line:1 char:1

                        + Set-SwisObject $swis -Uri $URI -Properties @{ HOSTNAME = 'HostnameTes ...

                        + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                            + CategoryInfo          : InvalidOperation: (:) [Set-SwisObject], FaultException`1

                            + FullyQualifiedErrorId : SwisError,SwisPowerShell.SetSwisObject

                         

                        It only seems to work if you use it to set and change custom properties....it doesnt appear that the API has access to Description, Alias...etc.

                        Thanks!

                          • Re: Invoke-SwisVerb Access Denied
                            erwabo

                            I can do this Get-SwisData $swis 'SELECT TOP 1 I.IpAddress FROM IPAM.IPNode I WHERE Where IpAddress >30 AND Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24'''

                             

                            But I need the first available between 10.8.63.30 - 10.8.63.230

                              • Re: Invoke-SwisVerb Access Denied
                                tomiannelli

                                I am confused by a couple of things. First, the IPAddress is stored as a varchar in the IPAM.Nodes table. Your WHERE clause is trying to compare it to an INT. That should not work at all. Second, I am not aware that IPAM will let you define random IPv4 ranges. You have to specify a standard mask. The IP addresses you are looking for do not break across IPv4 subnets nicely.

                                SubnetMaskInverse MaskSubnet SizeHost RangeBroadcast
                                10.8.63.0255.255.255.2240.0.0.313010.8.63.1  to  10.8.63.3010.8.63.31
                                10.8.63.32255.255.255.2240.0.0.313010.8.63.33  to  10.8.63.6210.8.63.63
                                10.8.63.64255.255.255.2240.0.0.313010.8.63.65  to  10.8.63.9410.8.63.95
                                10.8.63.96255.255.255.2240.0.0.313010.8.63.97  to  10.8.63.12610.8.63.127
                                10.8.63.128255.255.255.2240.0.0.313010.8.63.129  to  10.8.63.15810.8.63.159
                                10.8.63.160255.255.255.2240.0.0.313010.8.63.161  to  10.8.63.19010.8.63.191
                                10.8.63.192255.255.255.2240.0.0.313010.8.63.193  to  10.8.63.22210.8.63.223
                                10.8.63.224255.255.255.2240.0.0.313010.8.63.225  to  10.8.63.25410.8.63.255

                                So the only way I can think of is to get the whole set of available IP addresses in the 10.8.63.0/24 range and then cycle thru them. You could convert the last element to and INT and compare them so you get into the range.

                                 

                                I am still looking into modifying the hostname issue.

                                  • Re: Invoke-SwisVerb Access Denied
                                    erwabo

                                    Oops yeah that was the wrong command....and you are right that does NOT work at all =)

                                     

                                    I meant to paste $IP= Get-SwisData $swis 'SELECT TOP 1 I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24'' .This will pull the first available...

                                     

                                    Also if you change the above command to 'SELECT', it will return ALL the address in the subnet but it returns like 50 for EACH one....really bizarre.

                                     

                                    .I also did something like this:

                                     

                                    Get-SwisData $swis 'SELECT  I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayNa

                                    me = ''10.8.63.0/24''' | Where {$_.Split(".")[3] -ge 30 -and $_.Split(".")[3] -le 40}

                                     

                                    That worked to a degree, but still returns too many IPs, I need the FIRST one in that range.

                                     

                                    I figured out the hostname part. If you use the ReverseDNS cmdlet, it actually write the hostname in there as long as the attribute is not marked as available, it has to marked as used.

                                      • Re: Invoke-SwisVerb Access Denied
                                        tomiannelli

                                        So if you are not running the release candidate 4.6 of IPAM there is an issue: API returns lots of identical rows when running "SELECT [...] FROM IPAM.Subnet WHERE [...]" · Issue #52 · solarwinds/Ori…

                                        If you use a SELECT DISTINCT I.IPADDRESSS.... you should get your numbers.

                                          • Re: Invoke-SwisVerb Access Denied
                                            erwabo

                                            Okay that gets me VERY close, but now the only issue is that this Where {$_.Split(".")[3] -ge 30 -and $_.Split(".")[3] -le 50} also gives me IPs I dont want

                                             

                                            10.8.63.30

                                            10.8.63.36

                                            10.8.63.42

                                            10.8.63.39

                                            10.8.63.49

                                            10.8.63.50

                                            10.8.63.40

                                            10.8.63.44

                                            10.8.63.46

                                            10.8.63.38

                                            10.8.63.4 <--------

                                            10.8.63.33

                                            10.8.63.43

                                            10.8.63.32

                                            10.8.63.48

                                            10.8.63.41

                                            10.8.63.31

                                            10.8.63.35

                                            10.8.63.45

                                            10.8.63.37

                                            10.8.63.5 <---------

                                            10.8.63.34

                                            10.8.63.47

                                              • Re: Invoke-SwisVerb Access Denied
                                                erwabo

                                                I got it!! Thanks for the direction....but this seems to do it

                                                 

                                                $IP = Get-SwisData $swis 'SELECT DISTINCT I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24''' | Where {[int]$_.Split(".")[3] -ge 30 -and [int]$_.Split(".")[3] -le 50}

                                                $IP[0]

                                                  • Re: Invoke-SwisVerb Access Denied
                                                    tomiannelli

                                                    Interesting that the 4 and 5 were returned in that set. There is a way to fix that as I didn't catch it in my small test. You should cast the SPLIT as an Integer.

                                                    $TEST = Get-SwisData $swis 'SELECT DISTINCT I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''Muscatine Datacenter'''| Where { [int]($_.Split(".")[0]) -eq 10 -and [int]($_.Split(".")[1]) -eq 1 -and [int]($_.Split(".")[2]) -ge 190 -and [int]($_.Split(".")[2]) -le 191 -and [int]($_.Split(".")[3]) -ge 30 -and [int]($_.Split(".")[3]) -le 60}

                                                    That eliminates the 4 and the 5. When I opened up my range to a larger selection I replicated the same thing. In this example I used larger 255.255.254.0 network so I wanted the Where clause to match both the 190 and 191 third element. 

                                                     

                                                    If you don't care that your assignments don't happen in order then $IP[0] works.

                                                      • Re: Invoke-SwisVerb Access Denied
                                                        erwabo

                                                        So for anyone else who wants to jump of a bridge....this ended up being my final solution and worked like a charm. THANKS for all the help...MUCH appreciated!

                                                         

                                                        #Establish Connection to Orion and set connection variable

                                                         

                                                        $swis = Connect-Swis -Hostname orion.domain.com -Trusted

                                                        $vmname = 'TESTSERVER'

                                                         

                                                        #Get next available IP from a range of IPS in a subnet

                                                         

                                                        $IP = Get-SwisData $swis 'SELECT DISTINCT I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24'' ORDER BY' | Where {[int]$_.Split(".")[3] -ge 30 -and [int]$_.Split(".")[3] -le 50}

                                                         

                                                        $IP[0]

                                                         

                                                        #Mark IP as used

                                                         

                                                        Invoke-SwisVerb $swis IPAM.SubnetManagement ChangeIPStatus  @($IP[0], "Used")

                                                         

                                                        #Get IP Node ID from IPAM and set URI

                                                         

                                                        $Select = "SELECT I.IPNodeID,I.IPAddress FROM IPAM.IPNode I WHERE I.IPAddress = '" + $IP[0] + "'"

                                                        $R2 = Get-SwisData $swis $Select

                                                        $R2 | FT

                                                        $URI = 'swis://orion.domain.com/Orion/IPAM.IPNode/IpNodeId=' + $R2.IPNodeID

                                                         

                                                        #Set Host name in IPAM

                                                         

                                                        Set-SwisObject $swis -Uri $URI -Properties @{ DnsBackward = $vmname }

                                  • Re: Invoke-SwisVerb Access Denied
                                    tomiannelli

                                    You could use $d instead of the $IPKEY in the $HASTABLE. I just thought decimal sort would be faster.

                                    If you want to sort the IPv4 addresses just pass this function the array and it will return them sorted:

                                     

                                    function SortIPStrings ($ArrayofIPs) {

                                    $hashtable = @{}

                                    foreach ($ip in $ArrayofIPs)

                                    {

                                    $b = Split-String -Separator "." -Input $ip

                                    foreach ($c in $b)

                                    {

                                    $d = $d + [System.String]::Format("{0:X2}", [System.Convert]::ToUInt32($c))

                                    }

                                    $IPKey = [Convert]::ToInt64($d, 16)

                                    # $IPKEY

                                    $hashtable.Add($IPKEY, $ip)

                                    Clear-Variable d

                                    Clear-Variable IPKEY

                                    }

                                    $Sorted = $hashtable.GetEnumerator() | sort -Property name

                                    $ReturnSorted = $Sorted | Select-Object -Property Value -ExpandProperty Value

                                    $ReturnSorted

                                    }

                                      • Re: Invoke-SwisVerb Access Denied
                                        tomiannelli

                                        I was reminded of the IPAddress class so the function looks like:

                                        function SortIPStrings ($ArrayofIPs) {

                                        $hashtable = @{}

                                        foreach ($ip in $ArrayofIPs)

                                        {

                                        $IPKey= ([IPAddress]$ip).GetAddressBytes()

                                        $hashtable.Add($IPKEY, $ip)

                                        Clear-Variable IPKEY

                                        }

                                        $Sorted = $hashtable.GetEnumerator() | sort -Property name

                                        $ReturnSorted = $Sorted | Select-Object -Property Value -ExpandProperty Value

                                        $ReturnSorted

                                        }

                                      • Re: Invoke-SwisVerb Access Denied
                                        tomiannelli

                                        So the whole thing would look like:

                                         

                                        function SortIPStrings ($ArrayofIPs) {

                                             $hashtable = @{}

                                             foreach ($ip in $ArrayofIPs)

                                        {

                                             $IPKey= ([IPAddress]$ip).GetAddressBytes()

                                             $hashtable.Add($IPKEY, $ip)

                                             Clear-Variable IPKEY

                                        }

                                             $Sorted = $hashtable.GetEnumerator() | sort -Property name

                                             $ReturnSorted = $Sorted | Select-Object -Property Value -ExpandProperty Value

                                             $ReturnSorted

                                        }

                                        #Establish Connection to Orion and set connection variable

                                             $swis = Connect-Swis -Hostname orion.domain.com -Trusted

                                             $vmname = 'TESTSERVER'

                                        #Get next available IP from a range of IPS in a subnet

                                             $IP = Get-SwisData $swis 'SELECT DISTINCT I.IpAddress FROM IPAM.IPNode I WHERE Status=2 AND I.Subnet.DisplayName = ''10.8.63.0/24'' ORDER BY' | Where { [int]$_.Split(".")[3] -ge 30 -and [int]$_.Split(".")[3] -le 50 }

                                             $SortedIPS = SortIPStrings -ArrayofIPs $IP

                                             $SelectedIP = $SortedIPS[0]

                                        #Mark IP as used

                                             Invoke-SwisVerb $swis IPAM.SubnetManagement ChangeIPStatus  @($SelectedIP, "Used")

                                        #Get IP Node ID from IPAM and set URI

                                             $Select = "SELECT I.IPNodeID,I.IPAddress FROM IPAM.IPNode I WHERE I.IPAddress = '" + $SelectedIP + "'"

                                             $R2 = Get-SwisData $swis $Select

                                             $R2 | FT

                                             $URI = 'swis://orion.domain.com/Orion/IPAM.IPNode/IpNodeId=' + $R2.IPNodeID

                                        #Set Host name in IPAM

                                             Set-SwisObject $swis -Uri $URI -Properties @{ DnsBackward = $vmname }