1+ <#
2+ . SYNOPSIS
3+ Set a location on a group or device from an CSV input file
4+ . DESCRIPTION
5+ Uses PRTG API to set location.
6+
7+ . EXAMPLE
8+ PS C:\>
9+ . PARAMETER PRTGHost
10+ URL to PRTG core server
11+ . PARAMETER UserName
12+ Username of account to use for API calls
13+ . PARAMETER Passhash
14+ Passhash for account to use for API calls
15+ . PARAMETER TargetListCSV
16+ CSV list formatted by DeviceName, IP/DNS, Tag, Group
17+
18+ . OUTPUTS
19+ Object of all cloned Device
20+ . NOTES
21+ 2020-01-15 Version 1 Klas.Pihl@Atea.se
22+ Limit of 2500 devices.
23+ #>
24+ param (
25+ [CmdletBinding ()]
26+ [Parameter (Mandatory = $true , HelpMessage = " URL to PRTG core server, example https://yourserver.com" )]
27+ [uri ]$PRTGHost ,
28+ [Parameter (Mandatory = $true , HelpMessage = " PRTG username" )]
29+ [string ]$UserName ,
30+ [Parameter (Mandatory = $true , HelpMessage = " https://yourserver.com/api/getpasshash.htm?username=myuser&password=mypassword" )]
31+ [int ]$Passhash ,
32+ [Parameter (Mandatory = $true , HelpMessage = " Path to CSV with target devices" , ValueFromPipeline )]
33+ [string ]$TargetListCSV
34+
35+ )
36+ # region Self signed certificates
37+ add-type @"
38+ using System.Net;
39+ using System.Security.Cryptography.X509Certificates;
40+ public class TrustAllCertsPolicy : ICertificatePolicy {
41+ public bool CheckValidationResult(
42+ ServicePoint srvPoint, X509Certificate certificate,
43+ WebRequest request, int certificateProblem) {
44+ return true;
45+ }
46+ }
47+ "@
48+ Write-Verbose " Accepting self signed certificates"
49+ [System.Net.ServicePointManager ]::CertificatePolicy = New-Object TrustAllCertsPolicy
50+ <# PS7
51+ Write-Verbose "Adding class for validset"
52+ Class APINames : System.Management.Automation.IValidateSetValuesGenerator {
53+ [String[]] GetValidValues() {
54+ #$APINames = $APIkeys | Get-Member -Type NoteProperty | Select-Object -ExpandProperty Name
55+ $APINames = 'AddTag','DuplicateDevice','DuplicateGroup','GetAllDevices','GetGroups','Pause','ReSetLocation','Resume','SetLocation'
56+ return [String[]] $APINames
57+ }
58+ }
59+ #>
60+ # endregion Self signed certificates
61+ # region Functions
62+ function get-PRTGAPIData {
63+ [CmdletBinding ()]
64+ param (
65+ [Parameter (Mandatory = $true , HelpMessage = " Base url to PRTG core server, like https://prtg01.pihl.local" )]
66+ [uri ]$PRTGHost ,
67+
68+ [Parameter (Mandatory = $true , HelpMessage = " username=<user>%passhash=<[int]passhash>" )]
69+ [string ]$auth ,
70+
71+ [Parameter (Mandatory = $true )]
72+ [ValidateSet (' GetAllDevices' , ' DuplicateDevice' , ' Resume' , ' Pause' , ' GetGroups' )]
73+ [string ]$APIFunction ,
74+
75+ [Parameter (Mandatory = $false , HelpMessage = " Source device ID" )]
76+ [int ]$SourceID ,
77+
78+ [Parameter (Mandatory = $false , HelpMessage = " FQDN or IP address" )]
79+ [string ]$HostAddress ,
80+
81+ [Parameter (Mandatory = $false , HelpMessage = " Target group ID" )]
82+ [int ]$TargetGroupID ,
83+
84+ [Parameter (Mandatory = $false , HelpMessage = " PRTG sensor new name" )]
85+ [string ]$NewName
86+
87+ )
88+
89+ try {
90+ $api = $APIkeys .$APIFunction -f $SourceID , $NewName , $HostAddress , $TargetGroupID
91+
92+ Write-Verbose " Api call $api "
93+ [uri ]$uri = $PRTGHost.ToString ()+ $api.ToString ()+ $auth.ToString ()
94+ Write-Verbose " Complete URL: $uri "
95+ $request = Invoke-WebRequest - Uri $uri - ErrorAction Stop # -MaximumRedirection 1
96+ if ($request.StatusCode -ne 200 ) {
97+ Write-Verbose " Failed respons from uri"
98+ return $false
99+ }
100+ if ($request.content -and $APIFunction -like " get*" ) {
101+ $PRTG_Result = convertFrom-csv - ErrorAction Stop ($request.content ) - WarningAction SilentlyContinue | Select-Object * - ExcludeProperty * raw*
102+ return $PRTG_Result
103+ }
104+ } catch [System.Net.WebException ] {
105+ throw " Wrong URL, no respons from $PRTGHost `n $ ( $_.Exception ) "
106+ return $false
107+ } catch {
108+ throw " Could not get data from PRTG host $PRTGHost `n $ ( $_.Exception ) "
109+ return $false
110+ }
111+ return $true
112+ }
113+ function invoke-PRTGAPIData {
114+ [CmdletBinding ()]
115+ param (
116+ [Parameter (Mandatory = $true , HelpMessage = " Base url to PRTG core server, like https://prtg01.pihl.local" )]
117+ [uri ]$PRTGHost ,
118+
119+ [Parameter (Mandatory = $true , HelpMessage = " username=<user>%passhash=<[int]passhash>" )]
120+ [string ]$auth ,
121+
122+ [Parameter (Mandatory = $true , HelpMessage = " API key /api/function..." )]
123+ <# [ValidateSet('AddTag','DuplicateDevice','DuplicateGroup','GetAllDevices','GetGroups','Pause','ReSetLocation','Resume','SetLocation')] #($APIkeys | Get-Member -Type NoteProperty | Select-Object -ExpandProperty Name ) -join "','"
124+ #[ValidateSet([APINames])] #PS7
125+ [Validatescript({
126+ if (($APIkeys | Get-Member -Type NoteProperty | Select-Object -ExpandProperty Name) -contains $_) {$true}
127+ else { throw "Valid APIkeys; "+(($APIkeys | Get-Member -Type NoteProperty | Select-Object -ExpandProperty Name) -join ', ')}
128+ })]
129+ #>
130+ [string ]$API
131+ )
132+
133+
134+ [uri ]$uri = $PRTGHost.ToString ()+ $api.ToString ()+ $auth.ToString ()
135+ Write-Verbose " Complete URL: $uri "
136+ $request = Invoke-WebRequest - Uri $uri - MaximumRedirection 0 - ErrorAction Ignore # -MaximumRedirection 1
137+ $request | Export-Clixml - Force - Path ' output.xml'
138+ if ($request.StatusCode -eq 302 ) {
139+ Write-Verbose " Sucessfully created object"
140+ return $ (($request.RawContent | findstr ' Location' ).split(' =' )[1 ])
141+
142+ }
143+ if ($request.StatusCode -ne 200 ) {
144+ Write-Verbose " Failed respons from uri"
145+ return $false
146+ }
147+ if ($request.StatusCode -eq 200 ) {
148+ Write-Verbose " Successfull response"
149+ $PRTG_Result = convertFrom-csv - ErrorAction Stop ($request.content ) - WarningAction SilentlyContinue | Select-Object * - ExcludeProperty * raw*
150+ if ($PRTG_Result ) {
151+ return $PRTG_Result
152+ } else {
153+ return $true
154+ }
155+ }
156+
157+
158+ return $true
159+ }
160+ function read-TargetListCSV {
161+ <#
162+ . SYNOPSIS
163+ Reads CSV file from path and returns object
164+ . DESCRIPTION
165+ Verify that talbe headers is correct
166+ . EXAMPLE
167+ . PARAMETER Path
168+ File path to CSV
169+ . INPUTS
170+ CSV file path
171+ . OUTPUTS
172+ Object with imported CSV or $false
173+ . NOTES
174+ 2020-01-15 Version 1 Klas.Pihl@Atea.se
175+ #>
176+ [CmdletBinding ()]
177+ param (
178+ [Parameter (Mandatory = $true )]
179+ $Path
180+ )
181+ $script :ErrorActionPreference = ' Stop'
182+ $Headers = @ (
183+ ' DeviceName' ,
184+ ' IP/DNS' ,
185+ ' Tag' ,
186+ ' Group'
187+ )
188+ try {
189+ if (Test-Path - path $Path ) {
190+ Write-Verbose " Importing data from $Path "
191+ $ImportedData = Import-Csv - Path $Path - ErrorAction Stop
192+ $ImportedHeaders = $ImportedData | Get-Member - Type NoteProperty | Select-Object - ExpandProperty Name
193+ Write-Verbose " Imported Headers: $ImportedHeaders "
194+ if ([bool ](Compare-Object $ImportedHeaders $Headers )) {
195+ Write-Warning " Headers in imported CSV not identical with demand, colums should be; $ ( $Headers -join ' , ' | Out-String ) "
196+ return $false
197+ } else {
198+ return $ImportedData
199+ }
200+ } else {
201+ Write-Warning " $Path not vaild"
202+ return $false
203+ }
204+ } catch {
205+ Write-Warning " Can not import data from $path "
206+ return $false
207+ }
208+ }
209+ # endregion Functions
210+ # region Main
211+ $Global :APIkeys = [PSCustomObject ]@ {
212+ GetAllDevices = ' api/table.xml?content=devices&output=csvtable&columns=objid,device,host,name&count=2500&id={0}'
213+ DuplicateDevice = ' api/duplicateobject.htm?id={0}&name={1}&host={2}&targetid={3}' # SourceDeviceID, NewName, host/IP, group
214+ DuplicateGroup = ' api/duplicateobject.htm?id={0}&name={1}&targetid={2}' # TargetGroupID, NewName, LocationGroupID
215+ Resume = ' api/pause.htm?id={0}&action=1'
216+ Pause = ' api/pause.htm?id={0}&action=0'
217+ AddTag = ' api/setobjectproperty.htm?id={0}&name=tags&value={1}' # TargetObject,(tags separated by ',')
218+ SetLocation = ' api/setlonlat.htm?id={0}&location={1}&lonlat={2}' # objectID, Location address, "longitude,latitude"
219+ ReSetLocation = ' api/setlonlat.htm?id={0}' # objectID, Location address
220+ GetGroups = ' api/table.xml?content=groups&output=csvtable&columns=objid,probe,group,name&id={0}' # down from groupID
221+ }
222+ $Auth = " &username={0}&passhash={1}" -f $UserName , $Passhash
223+ # hämtar device,host och ID
224+ if (-not $SourceDeviceID ) {
225+ Write-Verbose " Quering PRTG core server of all devices"
226+ $SelectedDevice = get-PRTGAPIData - PRTGHost $PRTGHost - auth $Auth - APIFunction GetAllDevices | Out-GridView - PassThru - Title " Select one device to clone" | Select-Object - First 1
227+ [int ]$SourceDeviceID = $SelectedDevice | Select-Object - ExpandProperty id
228+ } else {
229+ $AllSDevices = get-PRTGAPIData - PRTGHost $PRTGHost - auth $Auth - APIFunction GetAllDevices
230+ $SelectedDevice = $SourceDeviceID | ForEach-Object {
231+ $AllSDevices | Where-Object ID -eq $_
232+ }
233+ }
234+ Write-Verbose " Selected device: $ ( $SelectedDevice | Out-String ) "
235+
236+ $TargetDevices = read-TargetListCSV - path $TargetListCSV | Select-Object * , GroupID, DeviceID, TagResult
237+ $Groups = $TargetDevices | Group-Object Group | Select-Object Name, ID
238+ Write-Verbose " Verifying group exist and otherwise create group"
239+
240+ # 2020-01-31 All objects
241+ $APISplat = @ {
242+ PRTGHost = $PRTGHost
243+ Auth = $Auth
244+ API = $ ($APIkeys.GetGroups )
245+ }
246+ $AllGroups = invoke-PRTGAPIData @APISplat - Verbose
247+ $APISplat = @ {
248+ PRTGHost = $PRTGHost
249+ Auth = $Auth
250+ API = $ ($APIkeys.GetAllDevices )
251+ }
252+ $AllDevices = invoke-PRTGAPIData @APISplat - Verbose
253+
254+ $AllObjects = ($AllDevices | Select-Object ID, object) + ( $AllGroups | Select-Object id, object)
255+
256+
257+
258+ # region tests
259+ # region test location
260+ $TargetDevice = 8926
261+ $LocationAddress = ' London'
262+ $LocationGPS = $null # '-14.92829,13.56812'
263+ $APISplat = @ {
264+ PRTGHost = $PRTGHost
265+ Auth = $Auth
266+ API = $ ($APIkeys.SetLocation -f $TargetDevice , $LocationAddress , $LocationGPS ) # API = $($APIkeys.SetLocationNoGPS -f $TargetDevice,$LocationAddress,$LocationGPS)
267+ }
268+ invoke-PRTGAPIData @APISplat - Verbose
269+ # endregion test location
270+ # region test groups
271+ $TargetGroupID = 50
272+ $APISplat = @ {
273+ PRTGHost = $PRTGHost
274+ Auth = $Auth
275+ # API = $($APIkeys.GetGroups -f $TargetGroupID) #API = $($APIkeys.SetLocationNoGPS -f $TargetDevice,$LocationAddress,$LocationGPS)
276+ APIFunction = ' GetGroups'
277+ TargetGroupID = $TargetGroupID
278+ }
279+ get-PRTGAPIData @APISplat
280+
281+
282+ $TargetGroupID = 50
283+ $APISplat = @ {
284+ PRTGHost = $PRTGHost
285+ Auth = $Auth
286+ API = $ ($APIkeys.GetGroups -f $TargetGroupID ) # API = $($APIkeys.SetLocationNoGPS -f $TargetDevice,$LocationAddress,$LocationGPS)
287+ # APIFunction = 'GetGroups'
288+ # TargetGroupID = $TargetGroupID
289+ }
290+ invoke-PRTGAPIData @APISplat - Verbose
291+ invoke-PRTGAPIData - API
292+ # endregion test groups
293+ # region test alldevices
294+ $TargetGroupID = $null # 8851
295+ $APISplat = @ {
296+ PRTGHost = $PRTGHost
297+ Auth = $Auth
298+ API = $ ($APIkeys.GetAllDevices -f $TargetGroupID )
299+ }
300+ invoke-PRTGAPIData @APISplat - Verbose
301+ # endregion test alldevices
302+ # endregion tests
303+
304+ # endregion Main
0 commit comments