W tym tygodniu otrzymaliśmy wyzwanie, które rzucił nam Paweł. Dotyczy ono automatycznego dodawania relacji między użytkownikiem a aplikacją prosto ze zgłoszenia. Sprawa co prawda przeciągnęła się kilka dni (każdy z nas pracuje zawodowo a ostatnio pracy mamy na prawdę sporo) ale nie bylibyśmy sobą, gdybyśmy nie podjęli się tego wyzwania. Czas na konkrety – zapraszamy! 🙂
Słowem wstępu…
Zanim przejdziemy do skryptu musicie zadać sobie pytanie: czy jesteśmy w stanie zaakceptować pewne problemy, które mogą wyniknąć z takiego działania? Z opisu Pawła wnioskujemy, iż relacja miała by dodawać się od razu. Nie to jednak – według nas – dobre rozwiązanie. Nie zawsze złożony wniosek oznacza przyznanie uprawnień – przynajmniej w większości organizacji. Dlatego lepiej będzie wykorzystać do tego Request Custom Menu – czyli dodanie pozycji w menu „Działania”.
Druga komplikacja wynika z działania samego API w ServiceDesk Plus. Producent niestety nie przewidział sytuacji, w której mamy dwóch użytkowników o tej samej nazwie wyświetlanej. Pewnie teraz zastanawiacie się o co chodzi z nazwą wyświetlaną – czyli niezbyt ważnym parametrem. Otóż – producent przy projektowaniu aplikacji uznał, że użytkownik to tak na prawdę CI, którego nazwą jest nazwa wyświetlana. A co w przypadku, gdy mamy dwóch Janów Kowalskich? W tym przypadku przy wysłaniu do API polecenia utworzenia relacji między AplikacjąX a Janem Kowalskim – relacja zostanie utworzona do pierwszego napotkanego Jana Kowalskiego w bazie. A co z tym drugim? Zostanie pominięty. Sposoby na ominięcie tego problemu trzeba szukać samemu…
Piszemy skrypt
W sumie moglibyśmy zmienić tytuł na „napisaliśmy skrypt”. Ale nie jest to adekwatny tytuł – my jesteśmy w stanie dać wam tylko pewnego rodzaju bazę. Każdy z was musi dostosować go do swoich potrzeb. Możecie popuścić wodzę fantazji i wykorzystując tę bazę stworzyć coś naprawdę fajnego 🙂
Ale przejdźmy do konkretów. Poniżej zamieszczamy przykładowy skrypt, który pobierze wartość z pola „Zasoby” oraz nazwę zgłaszającego i spróbuje wysłać poprzez API polecenie nawiązania relacji. W polu zasoby musi znaleźć się wartość, która odpowiada jakiemuś CI z naszego CMDB. Skrypt jest naprawdę prosty i trzeba go podrasować itd.
param ( [string]$jsonfile = $(throw 'COMPLETE_JSON_FILE jest wymagany!') ) $sdLink = "https://testsd.local" $sdApiKey = "techApiKey" $headCI = "People" $relationshipType = "Wykorzystywany przez" $jsonFileContent = Get-Content $jsonfile | ConvertFrom-Json $requestCi = $jsonFileContent.request.ASSET; $requesterName = $jsonFileContent.request.REQUESTER; if($requestCi -ne $null){ $addRelationApiInput = "<API version=`"1.0`" locale=`"pl`"><records><relationships><addrelationship><toci>$($requestCI)</toci><relationshiptype>$($relationshipType)</relationshiptype><relatedcis><citype>$($headCi)</citype><ci><name>$($requesterName)</name></ci></relatedcis></addrelationship></relationships></records></API>"; $apiLink = $sdLink + "/api/cmdb/cirelationships" $uploadData "format=xml&OPERATION_NAME=add&TECHNICIAN_KEY=$($sdApiKey)&INPUT_DATA=$($addRelationApiInput)"; [xml]$returnData = Invoke-WebRequest -Uri $apiLink -Method "POST" -Body $uploadData -TimeoutSec 20 -UseBasicParsing $message = "Wynik wykonywania skryptu: $($returnData.api.response.operation.result.status) $($returnData.api.response.operation.result.message)"; return $message } else{ return "Brak wartości w zasobach"; }
Ale co w przypadku gdy mamy więcej niż jeden zasób? Zasoby w pliku są zapisywane „po przecinku”. Z pomocą przychodzą nam funkcje split i foreach
</pre> <pre>param ( [string]$jsonfile = $(throw 'COMPLETE_JSON_FILE jest wymagany!') ) $sdLink = "https://testsd.local" $sdApiKey = "techApiKey" $headCI = "People" $relationshipType = "Wykorzystywany przez" $jsonFileContent = Get-Content $jsonfile | ConvertFrom-Json</pre> $requestCi = $jsonFileContent.request.ASSET; $requesterName = $jsonFileContent.request.REQUESTER; $message = "Wynik działania:`r`n" if($requestCI -ne $null){ $requestCIlist = $requestCi -split "," foreach($requestCiListItem in $requestCIlist){ $addRelationApiInput = "<API version=`"1.0`" locale=`"pl`"><records><relationships><addrelationship><toci>$($requestCiListItem)</toci><relationshiptype>$($relationshipType)</relationshiptype><relatedcis><citype>$($headCi)</citype><ci><name>$($requesterName)</name></ci></relatedcis></addrelationship></relationships></records></API>"; $apiLink = $sdLink + "/api/cmdb/cirelationships" $uploadData = "format=xml&OPERATION_NAME=add&TECHNICIAN_KEY=$($sdApiKey)&INPUT_DATA=$($addRelationApiInput)"; [xml]$returnData = Invoke-WebRequest -Uri $apiLink -Method "POST" -Body $uploadData -TimeoutSec 20 -UseBasicParsing $message += "dla zasobu $($requestCiListItem): $($returnData.api.response.operation.result.status) $($returnData.api.response.operation.result.message)`r`n"; } } else{ $message +="Brak zasobów w zgłoszeniu" }
Mamy nadzieje, że powyższy przykład użycia pomoże Wam w przygotowaniu skryptu dopasowanego do Waszej organizacji.