How to add ADFS Relying Party Trust SAMLAssertionConsumer using New-ADFSSamlEndpoint - powershell

I'm trying to build a script with powershell that will ask for a new uri to be added to an existing list of Relying Party Trust SAML Assertion Consumer Endpoints.
I've used this:
$samlEndpoint1 = New-ADFSSamlEndpoint -Protocol 'SAMLAssertionConsumer' -Uri 'https://moo.mydomain.local/samlprp-0/' -Binding 'POST' -IsDefault $false -Index 3
Set-ADFSRelyingPartyTrust -TargetName "ExistingRPT" -SamlEndpoint #($samlEndpoint1)
However this seems to remove the existing ones that are there and just leaves this new one. Therefore I was hoping this just added it to the existing list.
Does anyone please have any suggestions? Do I have to export the existing ones to some kind of array and then add to it?
Thanks for your time

Related

How to parse a response from Invoke-WebRequest

I fairly new to powershell, so I'm hoping someone may be able to help me out! I am trying to parse version numbers out of a webrequest and not sure of the best way to go about it. Basically, I'm using a website to store a package, and want to be able to call to a URL and download the file. The URL unfortunately only downloads the latest package, so I need to specify the version in the URL.
The goal is to pull the version list from the site, and then take the version number, and loop through, appending it to the download url for each version.
Currently to get the version, I have the following:
$api = 'http://localhost/package/NameOfProject/Packages()?
$format=json&$filter=id%20eq%20%27NameOfPackaget%27%20&$select=Version'
$response = Invoke-WebRequest -Uri $api | select-object Content
This will output
Content
-------
{"d":{"results":[{"Version":"3.3.14.2"},{"Version":"3.3.14.5"}],"count":0}}
Basically, I want it to just give me the versions (3.3.14.2), so that I can then use Invoke-WebRequest again with an -OutFile tag to save the files.
I'm probably approaching this in a completely incorrect way, so any guidance is appreciated!
You need to convert JSON in the Content property to the object and get all values of the the Version properties:
($response | ConvertFrom-Json).d.results.Version
Result:
3.3.14.2
3.3.14.5
beatcracker's helpful answer shows how to solve your problem with the Invoke-WebRequest cmdlet.
However, the Invoke-RestMethod cmdlet offers a simpler solution, because it automatically parses JSON text into objects ([pscustomobject] instances) that you can drill into with dot notation:
(Invoke-RestMethod $api).d.results.Version # add `[0]` to only extract the first version
If you need to exclude versions that match a pattern, such as those that have a --based suffix (e.g., 3.3.14.2-Test)):
#((Invoke-RestMethod $api).d.results.Version) -notmatch '-'

Is there a way to use Powershell to read local IE 11 cookies and replicate their data to other users on the same system?

I have a web based system that is called by a local PC system. The web system allows/controls interaction with a IP accessible device. Due to the simplistic nature of the base application interface to the web system (of which I have no control over), I have had to create a local cookie (using a web based configuration form) that stores site/install specific configuration information that is then used by the web system to interact with the internet accessible device for the installed site. The configuration is somewhat complicated. All of this already works and has been deployed to the initial customer site.
The issue is the PCs that are involved could be used by multiple people (in this instance 10 PCs that can be used by 10 or more employees each) with distinct logins to the PC(s) in question. This means setting up this complicated web configuration on each PC, 10 times. Lots of tedious room for errors.
I understand that I can not just copy a Win10 IE11 cookie from one user to another on a PC BUT is it possible to use Powershell to read the initial cookie that is built, extract the cookie information, and replicate/create a new cookie for all other users on that PC loading the new cookie with the same information in the base cookie?
I understand that I would likely need to run this from a user account with local admin right (in order to access the cookie area of other users) and can live with that if it avoids all the repetitive setup.
Is it possible to use Powershell and .Net to read a local cookie (given the URL) and extract the data from that cookie to be used to build new cookies for all other users on that PC for the initial URL?
Can't use IE plug-ins. Have not tried much else.
No code to show.
I am hoping for some code examples that demonstrate how to read from an existing cookie and how to write/create a cookie and load it with data, from Powershell.
You can refer examples of powershell scripts below will help you to read cookies.
$url = "https://www.linkedin.com"
$webrequest = Invoke-WebRequest -Uri $url -SessionVariable websession
$cookies = $websession.Cookies.GetCookies($url)
# Here, you can output all of $cookies, or you can go through them one by one.
foreach ($cookie in $cookies) {
# You can get cookie specifics, or just use $cookie
# This gets each cookie's name and value
Write-Host "$($cookie.name) = $($cookie.value)"
}
And if you're using PowerShell 2.0 and below, use System.Net.HTTPWebRequest
$url = "https://www.linkedin.com"
$cookiejar = New-Object System.Net.CookieContainer
$webrequest = [System.Net.HTTPWebRequest]::Create($url);
$webrequest.CookieContainer = $cookiejar
$response = $webrequest.GetResponse()
$cookies = $cookiejar.GetCookies($url)
# Here, you can output all of $cookies, or you can go through them one by one.
foreach ($cookie in $cookies) {
# You can get cookie specifics, or just use $cookie
# This gets each cookie's name and value
Write-Host "$($cookie.name) = $($cookie.value)"
}
Reference:
Getting Cookies using PowerShell
I did not get any examples for creating new cookie file from the existing files and share that cookie files with other users.

GoDaddy DNS API - Building a module with numerous commands

EDIT: I am looking for assistance on the GoDaddy API and how to form the request so I can delete a record. I can replace records and add new records and, of course, read records. I do not need assistance on building the module. Just having a problem figuring out the REST API piece for doing a delete on GoDaddy with the API.
I found this: Error 422 When Using Powershell to Update DNS Records on GoDaddy API
This gave me a good start. I have a number of functions I have already written to create or modify various different types of record. I have learned a lot along the way. Something that I have been unable to figure out so far is how to use the API to delete an existing record that is no longer needed.
I discovered that if I had an existing record of the same name and type and I tried to create a new, it would replace what was there with the new value. If it is just an A record and that is your desire, that's great. But if it is an MX or NS record, that is probably not the desired result. I am working on the helper functions to make sure that I don't blow away existing records before I publish to my module.
I am relatively new to reading API documentation and working with REST API's so I am probably just missing something basic, but if anyone could provide me with some guidance on how to configure my call so that I can clean up records that are no longer needed.
I am also having some issues formatting the SRV record properly so that it doesn't error out when I make the call. I am not sure where my problem is and I am not seeing anything in the documentation of allowed/expected values for Protocol, Service, etc.
Here is an excerpt of my code where I am calling:
try{
$ret = Invoke-WebRequest https://api.godaddy.com/v1/domains/domain/records/$type/$alias -method put -headers $headers -Body $json -ContentType "application/json"
if ($ret.StatusCode -eq 200) { Write-Verbose -Message "Success!" }
else { Write-Warning -Message "ERROR" }
} catch {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
$responseBody = $responseBody | ConvertFrom-Json | Format-Custom | Out-String
Write-Warning -Message "ERROR: $responseBody"
}
You will recognize this code block as it is largely taken intact from the aforementioned post. I am passing in $type as a valid record type (A, CNAME, etc.). $alias is the name of an existing record. $headers is a properly formatted header with a valid key/secret pair (I am able to Get and Put other records). I have tried omitting the body altogether to delete a value and that fails. I have tried doing the body with a JSON empty set ([], [{}]) as well as passing in data and TTL values with no value in the JSON. I can't get a successful query to work. I am testing with the following:
Invoke-WebRequest "https://api.godaddy.com/v1/domains/mydomain/records/A/test2" -method put -headers $header -ContentType "application/json" -Body '[{}]'
Any guidance or pointers to documentation that I haven't found would be greatly appreciated.
I had the same problem, it's about JSON encoding. I will show you a PHP example you can adapt to anything. The format that GoDaddy will provide is like this:
[{"":"","":"","":"",.....}]
I don't know from where comes the [] but I remove them, the parse json with regular PHP functions:
$json = str_replace("]","",$json);
//print_r($json);
$json = json_decode($json,true);
Now you will get the usable object to work with.
When send data to GoDaddy, do the same (I use curl)
$data = '[{"type":"'.$type.'","name":"'.$name.'","data":"'.$data.'","ttl":'.$ttl.'}]';
A full example that I build for updating my home server dynamic IP :) Check the functions Update() and get()
https://github.com/yo3hcv/Dynamic-DNS-hosting-home-or-mobile-with-GoDaddy/blob/master/pip.php
This maybe useful for others as I ran into the same unclarity about deleting a DNS record from a Godaddy domain using their API.
Godaddy doesn't support deleting an individual record.
From their support on the question whether it was possible to delete a record:
Dear Sir/Madam,
This API call does not exist at this time and it is something on our backlog to build out but there is no ETA to have it created. Current you can use the Put endpoint on the record type to replace all but the one you do not want to keep or you may go into our UI to remove it that way.
See their api documentation for what is available (at this date July 2020).
However, what you can do is replace all the existing records with a new set.
So suppose you have three A records with subdomain SD1, SD2 and SD3 and you want to remove SD2. You could sent an update command using:
curl -X PUT "https://api.godaddy.com/v1/domains/<yourdomain>/records/A" -H "accept: application/json" -H "Content-Type: application/json" -H "Authorization: <yourAPIKEY>" -d "[ { \"data\": \"<IP for SD1>\", \"name\": \"SD1\", \"ttl\": 3600 }, { \"data\": \"<IP for SD3>\", \"name\": \"SD3\", \"ttl\": 3600 }]"
Which will result in two A records one for SD1 and one for SD3. As long as you have at least one recordtype left (this also works for MX, MS, TXT) you will be able to remove others.
If you want to remove the last you have to go back to the Godaddy GUI, unfortunately.

New LDAP User with Powershell

I have the challenge to create new LDAP Users with a Powershell Script.
I have googled a lot but I found no good results...
This is my Code to get Users from the LDAP...
$authenticationType = [System.DirectoryServices.AuthenticationTypes]::ServerBind
$objSearcherRoot = New-Object System.DirectoryServices.DirectoryEntry("LDAP://***.local.com:777/ou=user,o=company", "uid=testuser,ou=system,o=company", "password" , $authenticationType)
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SizeLimit= 0
$objSearcher.PageSize = 1000
$objSearcher.SearchRoot = $objSearcherRoot
$objSearcher.Filter = "cn=$cn"
$result = $objSearcher.FindAll()
My Problem is, I don't know how to insert a new LDAP User (not Active Directory)
It would be really nice if someone could help me... ;)
Thanks
Yes, it's possible, I've done it. You need to bind to the LDAP server using a System.DirectoryServices.Protocols.LdapConnection object (let's say $c) and then create a System.DirectoryServices.Protocols.AddRequest object and populate its attributes (I'm only showing a couple in this example):
[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
[System.Reflection.Assembly]::LoadWithPartialName("System.Net")
$c = New-Object -TypeName System.DirectoryServices.Protocols.LdapConnection -ArgumentList "***.local.com:777,uid=testuser,ou=system,o=company", "password" , $authenticationType"
$c.Bind()
$r = New-Object -TypeName System.DirectoryServices.Protocols.AddRequest
$r.DistinguishedName = "uid= xxxx, ou=user, o=company"
$r.Attributes.Add((New-Object -TypeName System.DirectoryServices.Protocols.DirectoryAttribute -ArgumentList "objectclass",#("top","organizationalPerson","person","inetorgperson","inetuser","mailrecipient","pwmuser","posixAccount"))) | Out-Null
$r.Attributes.Add((New-Object -TypeName System.DirectoryServices.Protocols.DirectoryAttribute -ArgumentList "cn",($FirstName+" "+$LastName))) | Out-Null
Then just send the request:
$c.SendRequest($r)
LDAP does not support "inserts", but supports "adds". The LDAP client must create an entry and transmit that entry to the directory server using the ADD request. The server returns an ADD result to the LDAP client which contains information about the success or failure of the ADD request. So, check the documentation for information on transmitting an ADD request to the directory server and interpreting the subsequent response.
The LDAP client must have permission to ADD an entry (a user in this case). This involves using the BIND request to change the authorization state of the connection to one which permits adding an entry at the designated place in the directory information tree.
Perhaps this link will help.
You say "create new LDAP Users" but you could create AD users and then they would be available Using LDAP.
I used a script from Microsoft to do something similar.
If you look through the code, you should be able to see how they did it. We used their code with a few tweaks to do what we needed.
-jim

Invoke-WebRequest GetSystemWebProxy()

Under PowerShell 2.0 I know that you can set the proxy you would like to use without knowing the exact proxy settings by doing something like the following:
$proxy = [System.Net.WebRequest]::GetSystemWebproxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
Now, my question is if I don't know the proxy settings can I use the above and combine it with a PowerShell 3.0 Invoke-WebRequest. Here's what I was hoping to be able to do:
$proxy = [System.Net.WebRequest]::GetSystemWebproxy()
$proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
$WS.Proxy = $proxy
$login = Invoke-WebRequest https://website.com/login_form.html -SessionVariable WS
However, when I attempt to do this I get an error, (apparently from my company proxy) indicating that my credentials cannot be verified. I'm hoping that this will ultimately work, but perhaps I'm just making a simple mistake.
Maybe this can help, I keep it in my profile. It is using the new the $PSDefaultParameterValues preference variable to set the default proxy values for the new web cmdlets. The code detects if I'm in my office environment and set the settings accordingly. This saves me specifying the settings each time I use those commands.
if(Test-Connection myCorpProxy -Count 1 -Quiet)
{
$global:PSDefaultParameterValues = #{
'Invoke-RestMethod:Proxy'='http://myCorpProxy:8080'
'Invoke-WebRequest:Proxy'='http://myCorpProxy:8080'
'*:ProxyUseDefaultCredentials'=$true
}
}
Use can use this code :
$dest = "http://www.google.fr"
$proxyurl = ([System.Net.WebRequest]::GetSystemWebproxy()).GetProxy($dest)
Invoke-WebRequest $dest -Proxy $proxyurl -ProxyUseDefaultCredentials
The actual problem with your code above (even though Shay's is more elegant) is that you're trying to set a property on a variable before it exists. The SessionVariable "$WS" doesn't exist before you call Invoke-WebRequest but you're trying to set the .Proxy property above it.
If it worked at one point, you had probably created an instance of $WS previously and therefore were able to work with the object during testing but on a fresh/dry run when the script was processing top-down, it didn't yet exist.