From 5aa0dbed9a9af25442676cb6db91a13435818ead Mon Sep 17 00:00:00 2001 From: sheets9954 <51763822+sheets9954@users.noreply.github.com> Date: Wed, 12 Jun 2019 15:22:43 -0600 Subject: [PATCH 1/3] Add files via upload --- secretssingle.ps1 | 178 ++++++++++++++++++++++++++++++++++++++++++++++ secretssync.ps1 | 127 +++++++++++++++++++++++++++++++++ secretupdater.ps1 | 177 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 482 insertions(+) create mode 100644 secretssingle.ps1 create mode 100644 secretssync.ps1 create mode 100644 secretupdater.ps1 diff --git a/secretssingle.ps1 b/secretssingle.ps1 new file mode 100644 index 0000000..3c84252 --- /dev/null +++ b/secretssingle.ps1 @@ -0,0 +1,178 @@ +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$url = 'https://secrets.xxxxxxxx.com/webservices/sswebservice.asmx'; +$username = 'xxxxxxxx' +$password = 'xxxxxxxx' +$domain = 'xxxxxxxxxx' # leave blank for local users +#$idlist = Get-Content -Path C:\temp\rerun.txt +$proxy = New-WebServiceProxy -uri $url -UseDefaultCredential +$result1 = $proxy.Authenticate($username, $password, '', $domain) + +#set up log variable +$Savedata = @() + +#ITGlue api url +$hostitg = 'https://api.itglue.com' + +#ITGlue API key +$apikeyitg = 'ITG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + +#Set up headers for ITglue api transactions +$headersitg = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" +$headersitg.Add("x-api-key", $apikeyitg) +$headersitg.Add("Content-Type",'application/vnd.api+json') + +#url for all ITglue organizations +$url5 = $hostitg + "/organizations?page[number]=1&page[size]=1000" +$url5b = $hostitg + "/organizations?page[number]=2&page[size]=1000" +$url5c = $hostitg + "/organizations?page[number]=3&page[size]=1000" + +#get all organizations from ITGlue +$allitgorgs =@() +$allitgorgs += Invoke-RestMethod -Uri $url5 -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5b -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5c -Method Get -Header $headersitg -TimeoutSec 500 + + +if ($result1.Errors.length -gt 0){ +$result1.Errors[0] +exit +} +else +{ +$token = $result1.Token +} +$count = 7566 +$maxcount = 10000 + +$username = "" + $secretpass = "" + $urlforthis = "" + $notes = "" + $urlforthis = "" +$count + $action= "NONE???" + + $result2 = $proxy.GetSecret($token, $count, $false, $null) + if ($result2.Errors.length -gt 0){ + $result2.Errors[0] + } + else + { + $SaveData += New-Object PSObject + if($result2.Secret.Active -eq $true){ + $orgid = "" + $shortname = $result2.Secret.Name.Substring(0,4) + $shortname = $shortname.Trim(" ") + + + [string]$orgid = $allitgorgs.data | ? {$_.attributes.'short-name' -like $shortname} | select "id" + + if(($orgid -ne "")-and ($orgid -ne $null)){ + $itgposturl = $hostitg + "/organizations/" + $orgid.TrimStart("@{id=").TrimEnd("}") + "/relationships/passwords" + + + + + foreach($attrib in $result2.Secret.Items){ + if($attrib.FieldName -eq "Username"){$username = $attrib.Value} + if($attrib.FieldName -eq "Password"){$secretpass = $attrib.Value} + if($attrib.FieldName -eq "Notes"){$notes = $attrib.Value} + if($attrib.FieldName -like "Login URL*"){$urlforthis = $attrib.Value} + + } + + + if(($secretpass -eq "") -or ($secretpass -eq $null)){$secretpass = "NONE"} + + $urlforthis = $result2.Secret.Items[0].Value + if(($urlforthis -notlike "http*") -or ($urlforthis -notlike "*//*") ){$urlforthis = ""} + $body = @{ + "filter[name]" = $result2.Secret.Name + + } + $itggetorgpassurl = $hostitg + "/organizations/" + $orgid.TrimStart("@{id=").TrimEnd("}") + "/relationships/passwords" + $recordfound = Invoke-RestMethod -Uri $itggetorgpassurl -Method Get -Header $headersitg -body $body -TimeoutSec 500 + $itgpatchurl ="" + if($recordfound.data -ne $null){ + $itgpatchurl = $hostitg + "/passwords/" + $recordfound.data[0].id + $recordfound.data[0].id + + } + + if($urlforthis -ne ""){ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "url" = $urlforthis; + "notes" = $notes}}} + }else{ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "notes" = $notes}}} + } + + if($urlforthis -ne ""){ + $patchjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "url" = $urlforthis; + "notes" = $notes}}} + }else{ + $patchjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "notes" = $notes}}} + } + + $postjson = $postjson | ConvertTo-Json + $patchjson = $patchjson | ConvertTo-Json + + $response = "" + + if($itgpatchurl -eq ""){ + $response = Invoke-RestMethod -Uri $itgposturl -Method Post -Header $headersitg -Body $postjson -TimeoutSec 500 + $action = $response.data.attributes.'resource-url' + $postjson + $response + }else{ + $response = Invoke-RestMethod -Uri $itgpatchurl -Method Patch -Header $headersitg -Body $patchjson -TimeoutSec 500 + $action = "PATCH DATA" + $patchjson + $response + } + + + + + }else{ + $secretId + $shortname + $action = "ORG not Found in Glue. " + $shortname + "Org not Found in Glue" + #pause + } + }else{ + $action = "Skip" + "Skipping - " + $secretId + " - Active Flag is : " + $result2.Secret.Active + } + $SaveData | Add-Member -Name secretid -MemberType NoteProperty -Value $secretId -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name active -MemberType NoteProperty -Value $result2.Secret.Active -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Action -MemberType NoteProperty -Value $action -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Name -MemberType NoteProperty -Value $result2.Secret.Name -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name User -MemberType NoteProperty -Value $username -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Pass -MemberType NoteProperty -Value $secretpass -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name URL -MemberType NoteProperty -Value $urlforthis -erroraction 'silentlycontinue' + + } + + +$SaveData | export-csv -Path c:\temp\thyoticupdate2.csv -NoTypeInformation \ No newline at end of file diff --git a/secretssync.ps1 b/secretssync.ps1 new file mode 100644 index 0000000..ec1f849 --- /dev/null +++ b/secretssync.ps1 @@ -0,0 +1,127 @@ +$url = 'https://secrets.xxxxxxxxxxxx.com/webservices/sswebservice.asmx'; +$username = 'xxxxxxxxx' +$password = 'xxxxxxxxx' +$domain = 'xxxxxxxxxxx' # leave blank for local users +$idlist = Get-Content -Path C:\temp\rerun.txt +$proxy = New-WebServiceProxy -uri $url -UseDefaultCredential +$result1 = $proxy.Authenticate($username, $password, '', $domain) + +#set up log variable +$Savedata = @() + +#ITGlue api url +$hostitg = 'https://api.itglue.com' + +#ITGlue API key +$apikeyitg = 'ITG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + +#Set up headers for ITglue api transactions +$headersitg = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" +$headersitg.Add("x-api-key", $apikeyitg) +$headersitg.Add("Content-Type",'application/vnd.api+json') + +#url for all ITglue organizations +$url5 = $hostitg + "/organizations?page[number]=1&page[size]=1000" +$url5b = $hostitg + "/organizations?page[number]=2&page[size]=1000" +$url5c = $hostitg + "/organizations?page[number]=3&page[size]=1000" + +#get all organizations from ITGlue +$allitgorgs =@() +$allitgorgs += Invoke-RestMethod -Uri $url5 -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5b -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5c -Method Get -Header $headersitg -TimeoutSec 500 + + +if ($result1.Errors.length -gt 0){ +$result1.Errors[0] +exit +} +else +{ +$token = $result1.Token +} + +foreach($secretId in $idlist){ +$id + $action= "NONE???" + + $result2 = $proxy.GetSecret($token, $secretId, $false, $null) + if ($result2.Errors.length -gt 0){ + $result2.Errors[0] + } + else + { + $SaveData += New-Object PSObject + if($result2.Secret.Active -eq $true){ + $orgid = "" + $shortname = $result2.Secret.Name.Substring(0,4) + $shortname = $shortname.Trim(" ") + + + [string]$orgid = $allitgorgs.data | ? {$_.attributes.'short-name' -like $shortname} | select "id" + + if(($orgid -ne "")-and ($orgid -ne $null)){ + $itgposturl = $hostitg + "/organizations/" + $orgid.TrimStart("@{id=").TrimEnd("}") + "/relationships/passwords" + $secretId + $shortname + $itgposturl + $result2.Secret.Name + $result2.Secret.Items[0].FieldName + $result2.Secret.Items[0].Value + $result2.Secret.Items[1].FieldName + $result2.Secret.Items[1].Value + $result2.Secret.Items[2].FieldName + $result2.Secret.Items[2].Value + $result2.Secret.Items[3].FieldName + $result2.Secret.Items[3].Value + $secretpass = $result2.Secret.Items[2].Value; + if(($secretpass -eq "") -or ($secretpass -eq $null)){$secretpass = "NONE"} + + $urlforthis = $result2.Secret.Items[0].Value + if(($urlforthis -notlike "http*") -or ($urlforthis -notlike "//") ){$urlforthis = ""} + #if((isURI($urlforthis)) -ne $true) {$urlforthis = ""} + + if($urlforthis -ne ""){ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=($result2.Secret.Name.ToCharArray | select -first 140) -join ""; + "username"= $result2.Secret.Items[1].Value; + "password" = $secretpass; + "url" = $urlforthis; + "notes" = $result2.Secret.Items[3].Value}}} + }else{ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=($result2.Secret.Name.ToCharArray | select -first 140) -join ""; + "username"= $result2.Secret.Items[1].Value; + "password" = $secretpass; + "notes" = $result2.Secret.Items[3].Value}}} + } + + $postjson = $postjson | ConvertTo-Json + + $postjson + $postresponse = "" + $postresponse = Invoke-RestMethod -Uri $itgposturl -Method Post -Header $headersitg -Body $postjson -TimeoutSec 500 + $postresponse.data.attributes + $action = $postresponse.data.attributes.'resource-url' + + + }else{ + $secretId + $shortname + $action = "ORG not Found in Glue. " + $shortname + "Org not Found in Glue" + #pause + } + }else{ + $action = "Skip" + "Skipping - " + $secretId + " - Active Flag is : " + $result2.Secret.Active + } + $SaveData | Add-Member -Name secretid -MemberType NoteProperty -Value $secretId -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name active -MemberType NoteProperty -Value $result2.Secret.Active -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Action -MemberType NoteProperty -Value $action -erroraction 'silentlycontinue' + } + +} +$SaveData | export-csv -Path c:\temp\thyotic11.csv -NoTypeInformation \ No newline at end of file diff --git a/secretupdater.ps1 b/secretupdater.ps1 new file mode 100644 index 0000000..837b72c --- /dev/null +++ b/secretupdater.ps1 @@ -0,0 +1,177 @@ +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$url = 'https://secrets.xxxxxxxxxx.com/webservices/sswebservice.asmx'; +$username = 'xxxxxxxxxx' +$password = 'xxxxxxxxx' +$domain = 'xxxxxxxxxxx' # leave blank for local users +#$idlist = Get-Content -Path C:\temp\rerun.txt +$proxy = New-WebServiceProxy -uri $url -UseDefaultCredential +$result1 = $proxy.Authenticate($username, $password, '', $domain) + +#set up log variable +$Savedata = @() + +#ITGlue api url +$hostitg = 'https://api.itglue.com' + +#ITGlue API key +$apikeyitg = 'ITG.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' + +#Set up headers for ITglue api transactions +$headersitg = New-Object "System.Collections.Generic.Dictionary[[String],[String]]" +$headersitg.Add("x-api-key", $apikeyitg) +$headersitg.Add("Content-Type",'application/vnd.api+json') + +#url for all ITglue organizations +$url5 = $hostitg + "/organizations?page[number]=1&page[size]=1000" +$url5b = $hostitg + "/organizations?page[number]=2&page[size]=1000" +$url5c = $hostitg + "/organizations?page[number]=3&page[size]=1000" + +#get all organizations from ITGlue +$allitgorgs =@() +$allitgorgs += Invoke-RestMethod -Uri $url5 -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5b -Method Get -Header $headersitg -TimeoutSec 500 +$allitgorgs += Invoke-RestMethod -Uri $url5c -Method Get -Header $headersitg -TimeoutSec 500 + + +if ($result1.Errors.length -gt 0){ +$result1.Errors[0] +exit +} +else +{ +$token = $result1.Token +} +$count = 1 +$maxcount = 8000 +while($count -lt $maxcount){ +$username = "" + $secretpass = "" + $urlforthis = "" + $notes = "" + $urlforthis = "" +$count + $action= "NONE???" + + $result2 = $proxy.GetSecret($token, $count, $false, $null) + if ($result2.Errors.length -gt 0){ + $result2.Errors[0] + } + else + { + $SaveData += New-Object PSObject + if($result2.Secret.Active -eq $true){ + $orgid = "" + $shortname = $result2.Secret.Name.Substring(0,4) + $shortname = $shortname.Trim(" ") + + [string]$orgid = $allitgorgs.data | ? {$_.attributes.'short-name' -like $shortname} | select "id" + + if(($orgid -ne "")-and ($orgid -ne $null)){ + $itgposturl = $hostitg + "/organizations/" + $orgid.TrimStart("@{id=").TrimEnd("}") + "/relationships/passwords" + + + + + foreach($attrib in $result2.Secret.Items){ + if($attrib.FieldName -eq "Username"){$username = $attrib.Value} + if($attrib.FieldName -eq "Password"){$secretpass = $attrib.Value} + if($attrib.FieldName -eq "Notes"){$notes = $attrib.Value} + if($attrib.FieldName -like "Login URL*"){$urlforthis = $attrib.Value} + + } + + + if(($secretpass -eq "") -or ($secretpass -eq $null)){$secretpass = "NONE"} + + $urlforthis = $result2.Secret.Items[0].Value + if(($urlforthis -notlike "http*") -or ($urlforthis -notlike "*//*") ){$urlforthis = ""} + $body = @{ + "filter[name]" = $result2.Secret.Name + + } + $itggetorgpassurl = $hostitg + "/organizations/" + $orgid.TrimStart("@{id=").TrimEnd("}") + "/relationships/passwords" + $recordfound = Invoke-RestMethod -Uri $itggetorgpassurl -Method Get -Header $headersitg -body $body -TimeoutSec 500 + $itgpatchurl ="" + if($recordfound.data -ne $null){ + $itgpatchurl = $hostitg + "/passwords/" + $recordfound.data[0].id + $recordfound.data[0].id + + } + + if($urlforthis -ne ""){ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "url" = $urlforthis; + "notes" = $notes}}} + }else{ + $postjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "notes" = $notes}}} + } + + if($urlforthis -ne ""){ + $patchjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "url" = $urlforthis; + "notes" = $notes}}} + }else{ + $patchjson = @{"data" = @{"type" = "passwords"; + "attributes" = @{ + "name"=$result2.Secret.Name; + "username"= $username; + "password" = $secretpass; + "notes" = $notes}}} + } + + $postjson = $postjson | ConvertTo-Json + $patchjson = $patchjson | ConvertTo-Json + + $response = "" + + if($itgpatchurl -eq ""){ + $response = Invoke-RestMethod -Uri $itgposturl -Method Post -Header $headersitg -Body $postjson -TimeoutSec 500 + $action = $response.data.attributes.'resource-url' + $postjson + $response + }else{ + $response = Invoke-RestMethod -Uri $itgpatchurl -Method Patch -Header $headersitg -Body $patchjson -TimeoutSec 500 + $action = "PATCH DATA" + $patchjson + $response + } + + + + + }else{ + $secretId + $shortname + $action = "ORG not Found in Glue. " + $shortname + "Org not Found in Glue" + #pause + } + }else{ + $action = "Skip" + "Skipping - " + $secretId + " - Active Flag is : " + $result2.Secret.Active + } + $SaveData | Add-Member -Name secretid -MemberType NoteProperty -Value $count -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name active -MemberType NoteProperty -Value $result2.Secret.Active -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Action -MemberType NoteProperty -Value $action -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Name -MemberType NoteProperty -Value $result2.Secret.Name -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name User -MemberType NoteProperty -Value $username -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name Pass -MemberType NoteProperty -Value $secretpass -erroraction 'silentlycontinue' + $SaveData | Add-Member -Name URL -MemberType NoteProperty -Value $urlforthis -erroraction 'silentlycontinue' + + } + $count = $count + 1 +} +$SaveData | export-csv -Path c:\temp\thyoticupdate1.csv -NoTypeInformation \ No newline at end of file From 6251a1e9d286db699cf5e055b312cf29492e94e3 Mon Sep 17 00:00:00 2001 From: sheets9954 <51763822+sheets9954@users.noreply.github.com> Date: Wed, 12 Jun 2019 14:23:31 -0700 Subject: [PATCH 2/3] Rename secretssync.ps1 to secretsfullsync.ps1 --- secretssync.ps1 => secretsfullsync.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename secretssync.ps1 => secretsfullsync.ps1 (97%) diff --git a/secretssync.ps1 b/secretsfullsync.ps1 similarity index 97% rename from secretssync.ps1 rename to secretsfullsync.ps1 index ec1f849..317e006 100644 --- a/secretssync.ps1 +++ b/secretsfullsync.ps1 @@ -124,4 +124,4 @@ $id } } -$SaveData | export-csv -Path c:\temp\thyotic11.csv -NoTypeInformation \ No newline at end of file +$SaveData | export-csv -Path c:\temp\thyotic11.csv -NoTypeInformation From 9cb44175674c29342b4c802c5677557611861a5d Mon Sep 17 00:00:00 2001 From: sheets9954 <51763822+sheets9954@users.noreply.github.com> Date: Wed, 12 Jun 2019 14:26:44 -0700 Subject: [PATCH 3/3] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 830936c..e0481b4 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ # api-contest + +Thycotic -> IT Glue Migration/Integration + +We created and used these scripts to migrate and one way sync our Thycotic Secrets records into our IT Glue