Test-URL.psm1

<#
 .Synopsis
  List the Request, Response Values for any site, along with Name resolution for the URL, certificate details if any.
  Same will be done for all the redirected urls (except the name resolution part)
  
 .Description
  List the Request, Response Values for any site, along with Name resolution for the URL, certificate details if any.
  Same will be done for all the redirected urls (except the name resolution part)
  
 .Parameter URL
  URL, in complete format
  
 .Parameter Method
  HTTP Method, GET or HEAD
    
 .Example
  Test-URL -URL http://bing.com
  Test-URL -URL http://bing.com:80
  Test-URL -url http://bing.com -Method HEAD
  
#>


#------------------------------------------------------------------------------
#
#
# THIS CODE AND ANY ASSOCIATED INFORMATION ARE PROVIDED “AS IS” WITHOUT
# WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
# FOR A PARTICULAR PURPOSE. THE ENTIRE RISK OF USE, INABILITY TO USE, OR
# RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#
#------------------------------------------------------------------------------


function Test-URL () { 
Param (

    [Parameter(Mandatory=$true,
    ValueFromPipeline=$true,
    HelpMessage="Enter complete url; http://bing.com or http://bing.com:80")]
    [system.uri]$URL,

    [Parameter(Mandatory=$false)]
    [ValidateSet("GET", "HEAD")]
    [String]$Method  
 
)


$times = @()
$webres  = ''
$webres1 = $null
$test = $null
$test11 = $null
$redirectheaders = $null
$redirectheaders1 = $null
$errorweb = $null
$getcert = $null
$getcert1 = $null
$errorweb3 = $null
$uri = $null
$cont = $null
$cont1 = $null
$redirecturierror = $null
$weburierror = $null
$dnserrors = $null
$web = $null
$web1 = $null
$uriformaterrormessage = $null
$certerrore = $null
$certerror = $null
$certerror1 = $null
$redirecterror = $null
$certerrore1 = $null


#$url
if($url -eq ''){write-host "Enter complete url; http://bing.com or http://bing.com:80" ;Break}


#[system.uri]$url = 'https://www.microsoft.com'

$port = $url.Port
$uri = $url

# DNS Part
$TrimdURL =  $uri.Host 
Try{
$dns = Resolve-DnsName -Name $TrimdURL -Type A -ErrorAction SilentlyContinue
($dns | ft -Property Name, Namehost, Type, IP4Address, Querytype, Section | out-string)
}

catch [System.Net.WebException],[System.Exception] {
$dnserrors = $_
}
#$dnserrors.Exception.Message

Try{
# Creating Web Request
$web = [net.webrequest]::Create($uri)
if($Method -eq 'GET'){$web.Method={GET}}
if($Method -eq 'HEAD'){$web.Method={Head}}

# Disable Redirect and Cache Policy
$web.AllowAutoRedirect=$false
$cachepol = [System.Net.Cache.RequestCacheLevel]::NoCacheNoStore
$web.CachePolicy=$cachepol
}
Catch
{
$weburierror = $_
}
if($weburierror -ne $null){
$uriformaterrormessage = $($weburierror.Exception.InnerException.Message)
$uriformaterror = New-Object -TypeName PSObject
$uriformaterror | Add-Member -Name ErrorMessage -MemberType Noteproperty -Value $uriformaterrormessage 
$uriformaterror | Add-Member -Name OriginalString -MemberType Noteproperty -Value $($url.OriginalString;)
$uriformaterror | Add-Member -Name Example -MemberType Noteproperty -Value "Test-URL -URL https://bing.com"
($uriformaterror | FL | Out-String ).split("`n")  -match '\S'
#$web.Abort()
Break
}

try {
# Get Web response from the web request
$webres = $web.GetResponse()

# This is like Invoke-WebRequest PS Command
$test = [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject]::new($web.GetResponse())
$cont = $test.Content
$cont = ($cont -split '' | select -First 150) -join ''
}
catch [System.Net.WebException],[System.IO.IOException] {
    $errorweb =  $_

}

#Web error part

if($errorweb -ne $null){
 [array]$requestgeneralH = $web.Headers
 $requestgeneralV = New-Object -TypeName PSObject
 $requestgeneralV  | Add-Member -Name 'Request Headers' -MemberType NoteProperty -Value 'Request Headers'

for($i=0; $i -lt $requestgeneralH.Count; $i++){
$requestgeneralV | Add-Member -Name $requestgeneralH[$i] -MemberType Noteproperty -Value $web.Headers[$i]
}
$requestgeneralV | Add-Member -Name Method -MemberType NoteProperty -Value $web.Method
$requestgeneralV | Add-Member -Name Port -MemberType NoteProperty -Value $web.Address.Port
#"Request Headers"
($requestgeneralV | FL | Out-String ).split("`n")  -match '\S'
"`n"

#"Response-URI Headers"
$redirecterror = New-Object -TypeName PSObject
$actualerror = $($errorweb.Exception.Message) 
$redirecterror | Add-Member -Name ErrorMessage -MemberType Noteproperty -Value $actualerror


# get Cert details during web error
if($($url.Scheme) -eq 'https'){
Try{

$getcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($web.ServicePoint.Certificate)
#$getcert | Export-Certificate -FilePath "D:\net\go.test.cer"
$redirecterror | Add-Member -Name Thumbprint -MemberType Noteproperty -Value $($getcert.Thumbprint)
$redirecterror | Add-Member -Name Subject -MemberType Noteproperty -Value $($getcert.Subject)
$redirecterror | Add-Member -Name Issuer -MemberType Noteproperty -Value $($getcert.Issuer)
$redirecterror | Add-Member -Name NotAfter -MemberType Noteproperty -Value $($getcert.NotAfter)

}
Catch {
$certerrore = $_
}
if($certerrore -ne $null){
Write-host "$($certerrore.Exception.InnerException.Message);Certificate Error"  -ForegroundColor Red}

}


If($errorweb.Exception.Response -ne $null){
$redirecterror  | Add-Member -Name ResponseHeaders -MemberType Noteproperty -Value 'Response Headers'
$errstcode = $errorweb.Exception.Response.StatusCode.value__
$errstmsg = $errorweb.Exception.Response.StatusDescription
$redirecterror | Add-Member -Name StatusCode -MemberType Noteproperty -Value $errstcode 
$redirecterror | Add-Member -Name StatusDescription -MemberType Noteproperty -Value $errstmsg

#$errorweb.Exception.Response.ResponseUri.OriginalString
[array]$rederrorresp = $errorweb.Exception.Response.Headers
$redirecterror | Add-Member -Name Original-URI -MemberType NoteProperty -Value $($errorweb.Exception.Response.ResponseUri.OriginalString)
for($i=0; $i -lt $rederrorresp.Count; $i++){
$redirecterror | Add-Member -Name $rederrorresp[$i] -MemberType NoteProperty -Value $($errorweb.Exception.Response.Headers[$i])
}

}

if($errorweb.Exception.Response -eq $null){
$redirecterror | Add-Member -Name Original-URI -MemberType NoteProperty -Value $url.OriginalString
}

($redirecterror | FL | Out-String ).split("`n")  -match '\S'
$web.Abort()

break
}

 [array]$requestgeneralH = $web.Headers
 $requestgeneralV = New-Object -TypeName PSObject
 $requestgeneralV | Add-Member -Name 'Request Headers' -MemberType NoteProperty -Value 'Request Headers'

 for($i=0; $i -lt $requestgeneralH.Count; $i++){
$requestgeneralV | Add-Member -Name $requestgeneralH[$i] -MemberType Noteproperty -Value $web.Headers[$i]
}

$requestgeneralV | Add-Member -Name Method -MemberType NoteProperty -Value $web.Method
$requestgeneralV | Add-Member -Name Port -MemberType NoteProperty -Value $web.Address.Port
($requestgeneralV | FL | out-string).split("`n")  -match '\S'
"`n"

# Certificate Part

if($($url.Scheme) -eq 'https'){
Try{

$getcert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($web.ServicePoint.Certificate)
#$getcert | Export-Certificate -FilePath "D:\net\go.test.cer"

}
Catch {
$certerror = $_
}
if($certerror -ne $null){
Write-host "$($certerror.Exception.InnerException.Message);Certificate Error"  -ForegroundColor Red}

}

# Creating a variable to hold the current header value names avaialble for the Web Response
[array]$rehead = $webres.Headers

# Creating a Custom object to hold the Header names and values
$redirectheaders = New-Object -TypeName PSObject

# Updating the Request URI, Http status code and Description
#$redirectheaders | Add-Member -Name General -MemberType NoteProperty -Value 'General Info'
$redirectheaders | Add-Member -Name Request-URI -MemberType Noteproperty -Value $uri
$redirectheaders | Add-Member -Name ResponseHeaders -MemberType Noteproperty -Value 'Response Headers' 
$redirectheaders | Add-Member -Name StatusCode -MemberType Noteproperty -Value $($test.StatusCode)
$redirectheaders | Add-Member -Name StatusDescription -MemberType Noteproperty -Value $($test.StatusDescription)
$redirectheaders | Add-Member -Name Content -MemberType Noteproperty -Value $cont
if($( $url.Scheme) -eq 'https'){
$redirectheaders | Add-Member -Name Thumbprint -MemberType Noteproperty -Value $($getcert.Thumbprint)
$redirectheaders | Add-Member -Name Subject -MemberType Noteproperty -Value $($getcert.Subject)
$redirectheaders | Add-Member -Name Issuer -MemberType Noteproperty -Value $($getcert.Issuer)
$redirectheaders | Add-Member -Name NotAfter -MemberType Noteproperty -Value $($getcert.NotAfter)
}

# For loop to get the request header values from the Web Response and put them in the variable as diff objects
for($i=0; $i -lt $rehead.Count; $i++){
$redirectheaders | Add-Member -Name $rehead[$i] -MemberType Noteproperty -Value $webres.Headers[$i]
}


($redirectheaders | FL | out-string).split("`n")  -match '\S'
"`n"
"`n"

# Closing the Web Request
$web.Abort()


if ($($redirectheaders.location) -ne $null){

##############
##############


## Part 2 ################

Do{
$webres1 = ''
$times += $uri1




if($times.count -eq '1'){
$uri1 = $redirectheaders.location}
Else{$uri1 = $redirectheaders1.Location}

try{
$web1 = [net.webrequest]::Create($uri1)
$web1.AllowAutoRedirect=$false
$cachepol = [System.Net.Cache.RequestCacheLevel]::NoCacheNoStore
$web1.CachePolicy=$cachepol
}
Catch {
$redirecturierror = $_
}

if($redirecturierror -ne $null){
$redurilocerrmsg = "$($redirecturierror.Exception.InnerException.Message) This Module cannot redirect to location which are not in URL Format, yet."
$redirecturierrorobj1 = New-Object -TypeName PSObject
$redirecturierrorobj1 | Add-Member -Name Redirect-location -MemberType NoteProperty -Value $uri1
$redirecturierrorobj1 | Add-Member -Name Redirect-locationError -MemberType NoteProperty -Value $redurilocerrmsg
($redirecturierrorobj1 | FL | Out-String ).split("`n")  -match '\S'
$web.Abort()
Break
}


try {
$webres1 = $web1.GetResponse() 
$test11 = [Microsoft.PowerShell.Commands.BasicHtmlWebResponseObject]::new($web1.GetResponse())
$cont1 = $test11.Content
$cont1 = ($cont1 -split '' | select -First 150) -join ''

}
catch [System.Net.WebException],[System.IO.IOException] {
     $errorweb3 =  $_ 
}

if($errorweb3 -ne $null){
 [array]$requestgeneralH2 = $web1.Headers
$requestgeneralV2 = New-Object -TypeName PSObject
$requestgeneralV2 | Add-Member -Name Redirect-Request -MemberType NoteProperty -Value 'Redirect Request'
$requestgeneralV2 | Add-Member -Name Method -MemberType NoteProperty -Value $web1.Method
$requestgeneralV2 | Add-Member -Name Port -MemberType NoteProperty -Value $web1.Address.Port

for($i=0; $i -lt $requestgeneralH2.Count; $i++){
$requestgeneralV2 | Add-Member -Name $requestgeneralH2[$i] -MemberType Noteproperty -Value $web1.Headers[$i]
}
#Write-Host "Redirect Headers" -NoNewline -ForegroundColor Green
$requestgeneralV2 | FL
$web.Abort()
$web1.abort()
if($($url.Scheme) -eq 'https') {
$tcp.Close()
}

#"Redirect-URI Response"
$redirecterror1 = New-Object -TypeName PSObject

$actualerror1 = $($errorweb3.Exception.Message) 
$redirecterror1 | Add-Member -Name ErrorMessage -MemberType Noteproperty -Value $actualerror1



if($($web1.Address.Scheme) -eq 'https'){
Try{

$getcert1 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($web1.ServicePoint.Certificate)
$redirecterror1 | Add-Member -Name Thumbprint -MemberType Noteproperty -Value $($getcert1.Thumbprint)
$redirecterror1 | Add-Member -Name Subject -MemberType Noteproperty -Value $($getcert1.Subject)
$redirecterror1 | Add-Member -Name Issuer -MemberType Noteproperty -Value $($getcert1.Issuer)
$redirecterror1 | Add-Member -Name NotAfter -MemberType Noteproperty -Value $($getcert1.NotAfter)
#$getcert | Export-Certificate -FilePath "D:\net\$uri.cer"
}
Catch {
$certerrore1 = $_
}
if($certerrore1 -ne $null){
Write-host "$($certerrore1.Exception.InnerException.Message);Certificate Error"  -ForegroundColor Red}

}


If($errorweb3.Exception.Response -ne $null){
$redirecterror1  | Add-Member -Name Redirect-Response -MemberType Noteproperty -Value 'Redirect Response'
$errstcode1 = $errorweb3.Exception.Response.StatusCode.value__
$errstmsg1 = $errorweb3.Exception.Response.StatusDescription
$redirecterror1 | Add-Member -Name StatusCode -MemberType Noteproperty -Value $errstcode1 
$redirecterror1 | Add-Member -Name StatusDescription -MemberType Noteproperty -Value $errstmsg1

[array]$rederrorresp1 = $errorweb3.Exception.Response.Headers

$redirecterror1 | Add-Member -Name Redirect-URI -MemberType NoteProperty -Value $($errorweb3.Exception.Response.ResponseUri.OriginalString)

for($i=0; $i -lt $rederrorresp1.Count; $i++){
$redirecterror1 | Add-Member -Name $rederrorresp1[$i] -MemberType NoteProperty -Value $($errorweb3.Exception.Response.Headers[$i])
}


}

If($errorweb3.Exception.Response -eq $null){
$redirecterror1 | Add-Member -Name Redirect-URI -MemberType NoteProperty -Value $uri1

}

($redirecterror1 | FL | Out-String ).split("`n")  -match '\S'

break
}

 [array]$requestgeneralH2 = $web1.Headers
 $requestgeneralV2 = New-Object -TypeName PSObject
 $requestgeneralV2 | Add-Member -Name Redirect-Requests -MemberType NoteProperty -Value 'Redirect Request'
 $requestgeneralV2 | Add-Member -Name Method -MemberType NoteProperty -Value $web1.Method
 $requestgeneralV2 | Add-Member -Name Port -MemberType NoteProperty -Value $web1.Address.Port

for($i=0; $i -lt $requestgeneralH2.Count; $i++){
$requestgeneralV2 | Add-Member -Name $requestgeneralH2[$i] -MemberType Noteproperty -Value $web1.Headers[$i]
}


($requestgeneralV2 | FL | out-string).split("`n")  -match '\S'
"`n"

# Certificate Part

if($($web1.Address.Scheme) -eq 'https'){
Try{

$getcert1 = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2Collection($web1.ServicePoint.Certificate)

#$getcert | Export-Certificate -FilePath "D:\net\$uri.cer"
}
Catch {
$certerror1 = $_
}
if($certerror1 -ne $null){
Write-host "$($certerror1.Exception.InnerException.Message);Certificate Error"  -ForegroundColor Red}

}



[array]$rehead1 = $webres1.Headers
$redirectheaders1 = New-Object -TypeName PSObject
#$redirectheaders1 | Add-Member -Name General -MemberType NoteProperty -Value 'General Info'
$redirectheaders1 | Add-Member -Name Redirect-URI -MemberType Noteproperty -Value $uri1 
$redirectheaders1 | Add-Member -Name Redirect-Response -MemberType NoteProperty -Value 'Redirect Response'
$redirectheaders1 | Add-Member -Name StatusCode -MemberType Noteproperty -Value $($test11.StatusCode) 
$redirectheaders1 | Add-Member -Name StatusDescription -MemberType Noteproperty -Value $($test11.StatusDescription) 
$redirectheaders1 | Add-Member -Name Content -MemberType Noteproperty -Value $cont1
if($($web1.Address.Scheme) -eq 'https'){
$redirectheaders1 | Add-Member -Name Thumbprint -MemberType Noteproperty -Value $($getcert1.Thumbprint)
$redirectheaders1 | Add-Member -Name Subject -MemberType Noteproperty -Value $($getcert1.Subject)
$redirectheaders1 | Add-Member -Name Issuer -MemberType Noteproperty -Value $($getcert1.Issuer)
$redirectheaders1 | Add-Member -Name NotAfter -MemberType Noteproperty -Value $($getcert1.NotAfter)
}


for($i=0; $i -lt $rehead1.Count; $i++){
$redirectheaders1 | Add-Member -Name $rehead1[$i] -MemberType Noteproperty -Value $webres1.Headers[$i] 
}


#Write-Host "Response Headers" -NoNewline -ForegroundColor Green
($redirectheaders1 | FL| out-string).split("`n")  -match '\S'
"`n"


# Check to limit the number of Redirections
if($times.Count -gt '20')
{
"Maximum redirection limit for this module reached"
$web.Abort()
$web1.abort()
Break
}

}

While ($redirectheaders1.location -ne $null   )

if($web1 -ne $null)
{$web1.abort()}

}

}

Export-ModuleMember -Function Test-URL