Need to Trim a url in powershell script - powershell

I have a URL www.example.com:1234/ and I need to trim above in to 2 variables:
example.com
00234
first digit of port will be replaced by 00
Can this be achieved in PowerShell?

here's one way to do it ... [grin]
# fake reading in a list of URLs
# in real life, use Get-Content
$UrlList = #'
www.example.com:1234/
www3.example.net:9876
www.other.example.org:5678/
'# -split [environment]::NewLine
$Regex = '^www.*?\.(?<Domain>.+):(?<Port>\d{1,}).*$'
$Results = foreach ($UL_Item in $UrlList)
{
$Null = $UL_Item -match $Regex
[PSCustomObject]#{
URL = $UL_Item
Domain = $Matches.Domain
OriginalPort = $Matches.Port
Port = '00{0}' -f (-join $Matches.Port.ToString().SubString(1))
}
}
$Results
output ...
URL Domain OriginalPort Port
--- ------ ------------ ----
www.example.com:1234/ example.com 1234 00234
www3.example.net:9876 example.net 9876 00876
www.other.example.org:5678/ other.example.org 5678 00678
comment out or delete any unwanted properties. [grin]
per request, a simplified version ... [grin]
$UserInput = 'www.example.com:1234/'
$Regex = '^www.*?\.(?<Domain>.+):(?<Port>\d{1,}).*$'
$Null = $UserInput -match $Regex
$Domain = $Matches.Domain
$Port = '00{0}' -f (-join $Matches.Port.SubString(1))
$Domain
$Port
output ...
example.com
00234
hope that helps,
lee

[uri]$url = 'www.example.com:1234/'
$Value1 = ($url.Scheme).Replace('www.','')
$Value2 = "00" + ($url.AbsolutePath).Substring(1).TrimEnd('/')

To offer an improvement to James C.'s answer:
# Input URL string
$urlText = 'www.example.com:1234/'
# Prepend 'http://' and cast to [uri] (System.Uri), which
# parses the URL string into its constituent components.
$urlObj = [uri] "http://$urlText"
# Extract the information of interest
$domain = $urlObj.Host -replace '^www\.' # -> 'example.com'
$modifiedPort = '00' + $urlObj.Port.ToString().Substring(1) # -> '00234'

Related

Event logs XML to CSV - missing SystemTime

I am trying to export some filtered logs out to CSV. Everything works right except the event date and time - comes out blank. Here is the code - any thoughts would be most appreciated. Thanks.
# Prepare Variables
Param (
[parameter(Mandatory=$false,Position=0)][String]$ComputerName = "localhost",
[parameter(Mandatory=$false,Position=1)][Int]$Hours = 24)
# Create an Array to hold our returnedvValues
$InsecureLDAPBinds = #()
# Grab the appropriate event entries
$Events = Get-WinEvent -ComputerName $ComputerName -FilterHashtable #{Logname='Directory Service';Id=2889; StartTime=(get-date).AddHours("-$Hours")}
# Loop through each event and output the
ForEach ($Event in $Events) {
$eventXML = [xml]$Event.ToXml()
# Build Our Values
$Client = ($eventXML.event.EventData.Data[0])
$IPAddress = $Client.SubString(0,$Client.LastIndexOf(":")) #Accomodates for IPV6 Addresses
$Port = $Client.SubString($Client.LastIndexOf(":")+1) #Accomodates for IPV6 Addresses
$TimeCreated = $eventXML.System.TimeCreated.SystemTime
$User = $eventXML.event.EventData.Data[1]
Switch ($eventXML.event.EventData.Data[2])
{
0 {$BindType = "Unsigned"}
1 {$BindType = "Simple"}
}
# Add Them To a Row in our Array
$Row = "" | select IPAddress,Port,TimeCreated,User,BindType
$Row.IPAddress = $IPAddress
$Row.Port = $Port
$Row.TimeCreated = $TimeCreated
$Row.User = $User
$Row.BindType = $BindType
# Add the row to our Array
$InsecureLDAPBinds += $Row
}
# Dump it all out to a CSV.
Write-Host $InsecureLDAPBinds.Count "records saved to .\InsecureLDAPBinds.csv for Domain Controller" $ComputerName
$InsecureLDAPBinds | Export-CSV -NoTypeInformation .\InsecureLDAPBinds.csv

Grab parameters from url and drop them to powershell variables

i have a powershell listener running on my windows-box. Code from Powershell-Gallery: https://www.powershellgallery.com/packages/HttpListener/1.0.2
The "Client" calls the listener with the following example url:
With Powershell i do:
invoke-webrequest -Uri "http://127.0.0.1:8888/Test?id='1234'&param2='##$$'&param3='This is a test!'"
I have no idea, how to drop the parameters from the url to variables with the same name in powershell. I need to bring the parameters to powershellvariables to simply echo them. this is my last missing part. The parameters are separated with & and parameternames are case-sensitive.
To be more detailed, the id from the url should be in a powershell-variable named $id with the value 1234. The Variables can contain spaces, special characters, numbers, alphas. They are case sensitive. The parametervalue could be "My Name is "Anna"! My Pets Name is 'Bello'. " with all the "dirty" Characters like '%$"!{[().
Can someone point me to the right way how to get this solved?
In a valid url, the $ characters should have been escaped to %24
The other 'dirty' character % in Url escaped form is %25
This means the example url is invalid and should be:
$url = "http://127.0.0.1:8888/Test?id='1234'&param2='##%24%24'&param3='This is a test!'"
Then the following does work
$url = "http://127.0.0.1:8888/Test?id='1234'&param2='##%24%24'&param3='This is a test!'"
if ($url -is [uri]) {
$url = $url.ToString()
}
# test if the url has a query string
if ($url.IndexOf('?') -ge 0) {
# get the part of the url after the question mark to get the query string
$query = ($url -split '\?')[1]
# or use: $query = $url.Substring($url.IndexOf('?') + 1)
# remove possible fragment part of the query string
$query = $query.Split('#')[0]
# detect variable names and their values in the query string
foreach ($q in ($query -split '&')) {
$kv = $($q + '=') -split '='
$varName = [uri]::UnescapeDataString($kv[0]).Trim()
$varValue = [uri]::UnescapeDataString($kv[1])
New-Variable -Name $varname -Value $varValue -Force
}
}
else {
Write-Warning "No query string found as part of the given URL"
}
Prove it by writing the newly created variables to the console
Write-Host "`$id = $id"
Write-Host "`$param2 = $param2"
Write-Host "`$param3 = $param3"
which in this example would print
$id = '1234'
$param2 = '##$$'
$param3 = 'This is a test!'
However, I personally would not like to create variables like this, because of the risk of overwriting already existing ones.
I think it would be better to store them in a hash like this:
# detect variable names and their values in the query string
# and store them in a Hashtable
$queryHash = #{}
foreach ($q in ($query -split '&')) {
$kv = $($q + '=') -split '='
$name = [uri]::UnescapeDataString($kv[0]).Trim()
$queryHash[$name] = [uri]::UnescapeDataString($kv[1])
}
$queryHash
which outputs
Name Value
---- -----
id '1234'
param2 '##$$'
param3 'This is a test!'

cutting a portion of url in powershell

I have a few URLs which would need to cut and separate the first part of the each URL, i.e example1.com, example2.com, example3.com from each line and store in a variable
Contents in url.csv
https://example1.com/v1/test/f3de-a8c6-464f-8166-9fd4
https://example2.com/v1/test/14nf-d7jc-54lf-fd90-fds8
https://example3.com/v1/test/bd38-17gd-2h65-0j3b-4jf6
Script:
$oldurl = Import-CSV "url.csv"
$newurl = $oldurl.list -replace "https://"
This would replace https://, however the rest of each cannot be hard coded as those values can change.
What could be change code change required to cut anything from and after /v1/ along with https://?
$list = #(
"https://example1.com/v1/test/f3de-a8c6-464f-8166-9fd4",
"https://example2.com/v1/test/14nf-d7jc-54lf-fd90-fds8",
"https://example3.com/v1/test/bd38-17gd-2h65-0j3b-4jf6"
)
$result = $list | %{
$uri = [System.Uri] $_
$uri.Authority
}
$result
See System.Uri properties to potentially assemble the information you need in your result list.
This will cut off anything after "/v1/" and it self. Is that what you want?
$string = "https://example1.com/v1/test/f3de-a8c6-464f-8166-9fd4"
$string = $string -replace "https://"
$pos = $string.IndexOf("/v1/")
$result = $string.Substring(0, $pos)
$result
Output: example1.com

Use 2 arrays in one loop

I want to use 2 arrays in one loop, but I am failing each time to find out how?
$hosts = "1.1.1.1,2.2.2.2,3.3.3.3"
$vmotionIPs = "1.2.3.4,5.6.7.8,7.8.9.0"
foreach ($host in $hosts) ($vmotionIP in $vmotionIPs)
New-VMHostNetworkAdapter -VMHost $host-VirtualSwitch myvSwitch `
-PortGroup VMotion -IP $vmotionIP -SubnetMask 255.255.255.0 `
-VMotionEnabled $true
I know the above syntax is wrong but I just hope it conveys my goal here.
The most straightforward way is to use a hashtable:
$hosts = #{
"1.1.1.1" = "1.2.3.4" # Here 1.1.1.1 is the name and 1.2.3.4 is the value
"2.2.2.2" = "5.6.7.8"
"3.3.3.3" = "7.8.9.0"
}
# Now we can iterate the hashtable using GetEnumerator() method.
foreach ($hostaddr in $hosts.GetEnumerator()) { # $host is a reserved name
New-VMHostNetworkAdapter -VMHost $hostaddr.Name -VirtualSwitch myvSwitch `
-PortGroup VMotion -IP $$hostaddr.Value -SubnetMask 255.255.255.0 `
-VMotionEnabled $true
}
First, your arrays aren't arrays. They're just strings. To be arrays you'll need to specify them as:
$hosts = "1.1.1.1","2.2.2.2","3.3.3.3";
$vmotionIPs = "1.2.3.4","5.6.7.8","7.8.9.0";
Second, $host is a reserved variable. You should avoid using that.
Third, I'm assuming you want the first host to use the first vmotionIP, the second host to use the second vmotionIP, etc.
So, the standard way to do this is to do this:
$hosts = "1.1.1.1","2.2.2.2","3.3.3.3";
$vmotionIPs = "1.2.3.4","5.6.7.8","7.8.9.0";
for ($i = 0; $i -lt $hosts.Count; $i++) {
New-VMHostNetworkAdapter -VMHost $hosts[$i] `
-VirtualSwitch myvSwitch `
-PortGroup VMotion `
-IP $vmotionIPs[$i] `
-SubnetMask 255.255.255.0 `
-VMotionEnabled $true;
}
Or you can use the hashtable method #AlexanderObersht describes. This method changes the least about your code, however.
Thank you for your information. What you suggested worked for me some other script but i ended up achieving this using the following.
first i generated a series of ip addresses like this
$fixed = $host1.Split('.')[0..2]
$last = [int]($host.Split('.')[3])
$max = Read-Host "Maximum number of hosts that you want to configure?"
$max_hosts = $max - 1
$hosts =
$last..($last + $max_hosts) | %{
[string]::Join('.',$fixed) + "." + $_
}
and then i did
$vMotion1_ip1 = Read-Host "the 1st vmotion ip of the 1st host?"
$fixed = $vMotion1_ip1.Split('.')[0..2]
$last = [int]($vMotion1_ip1.Split('.')[3])
$max_hosts = $max - 1
$vMotions =
$last..($last + $max_hosts) | %{
[string]::Join('.',$fixed) + "." + $_
}
$first = [string]::Join('.',$fixed) + "." + $_
foreach ($vmhost in $vMotions) {write-host "$vmhost has the following network ("$first$(($last++))", "255.255.255.0")"}
not exactly like this but something along this way.
Thank you all for your answers. I ended up using the do while instead. This allows us to loop through as many as arrays as we want at the same time or include multiple arrays in one loop.
$hosts = #("1.1.1.1","2.2.2.2","3.3.3.3")
$vmotionIPs = #("1.2.3.4","5.6.7.8","7.8.9.0")
[int]$n = 0
do
{
$vmhost = $hosts[$n]
$vmotionIP = $vmotionIPs[$n]
New-VMHostNetworkAdapter -VMHost $vmhost-VirtualSwitch myvSwitch -PortGroup VMotion -IP $vmotionIP -SubnetMask 255.255.255.0 -VMotionEnabled $true
$n++
} while ($n -lt $hosts.count)

Checking for a range in Powershell

I'm trying to write a script that will get an IP address of a computer and check to see whether it falls in a specific range of IPs. So for example, if the IP of the machine is 192.168.0.5, the script will check to see if it falls between the range 192.168.0.10 to 192.168.0.20. So far, my script is only able to get IPs of remote machines, but I just can't figure out how I would check if the IP is in a specific range. I'd appreciate any suggestions. Thank you.
It might be easiest to let .NET do the work - there's an IPAddress class that can parse them to their numeric values for comparison. Here's a function that you can drop into your profile (or add to a module, or however you prefer to add PS functions):
function IsIpAddressInRange {
param(
[string] $ipAddress,
[string] $fromAddress,
[string] $toAddress
)
$ip = [system.net.ipaddress]::Parse($ipAddress).GetAddressBytes()
[array]::Reverse($ip)
$ip = [system.BitConverter]::ToUInt32($ip, 0)
$from = [system.net.ipaddress]::Parse($fromAddress).GetAddressBytes()
[array]::Reverse($from)
$from = [system.BitConverter]::ToUInt32($from, 0)
$to = [system.net.ipaddress]::Parse($toAddress).GetAddressBytes()
[array]::Reverse($to)
$to = [system.BitConverter]::ToUInt32($to, 0)
$from -le $ip -and $ip -le $to
}
Usage looks like:
PS> IsIpAddressInRange "192.168.0.5" "192.168.0.10" "192.168.0.20"
False
PS> IsIpAddressInRange "192.168.0.15" "192.168.0.10" "192.168.0.20"
True
i write a little function to do this:
function Test-IpAddressInRange {
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)][ipaddress]$from,
[Parameter(Position = 1, Mandatory = $true)][ipaddress]$to,
[Parameter(Position = 2, Mandatory = $true)][ipaddress]$target
)
$f=$from.GetAddressBytes()|%{"{0:000}" -f $_} | & {$ofs='-';"$input"}
$t=$to.GetAddressBytes()|%{"{0:000}" -f $_} | & {$ofs='-';"$input"}
$tg=$target.GetAddressBytes()|%{"{0:000}" -f $_} | & {$ofs='-';"$input"}
return ($f -le $tg) -and ($t -ge $tg)
}
test result:
PS C:\> Test-IpAddressInRange "192.168.0.1" "192.168.0.100" "192.168.0.1"
True
PS C:\> Test-IpAddressInRange "192.168.0.1" "192.168.0.100" "192.168.0.100"
True
PS C:\> Test-IpAddressInRange "192.168.90.1" "192.168.100.100" "192.168.101.101"
False
PS C:\>
It's easy if mask is 255.255.255.0
in this case you can do something like this:
$a = [ipaddress]"192.168.0.5"
10..20 -contains $a.IPAddressToString.split('.')[3]
true
For different submask you have to check each ip's octect.
If you're into the whole brevity thing, here is a functional hybrid of AndyHerb's comment and E.Z. Hart's answer:
function IsIpAddressInRange {
param(
[System.Version] $IPAddress,
[System.Version] $FromAddress,
[System.Version] $ToAddress
)
$FromAddress -le $IPAddress -and $IPAddress -le $ToAddress
}
Examples:
IsIpAddressInRange "192.168.1.50" "192.168.1.30" "192.168.1.100"
True
IsIpAddressInRange "192.168.25.75" "192.168.25.0" "192.168.25.255"
True
IsIpAddressInRange "192.168.36.240" "192.168.36.0" "192.168.36.100"
False
IsIpAddressInRange "192.168.36.240" "192.168.33.0" "192.168.37.0"
True
For seeing if an IP is in range 192.168.1.10 to 192.168.1.20, for example, you can use regex and the -match operator
$ip -match "192\.168\.1\.0?(1\d)|20"
The 0? is to allow a leading 0.
Similarly, for any range, you can use a regex.
For very simple range, use string split on . and operate on the components.
Came across this one when googling, rather high hit. Just wanted to say that at least in powershell 4 and 5 it's a lot easier:
$range = "10.10.140.0-10.11.15.0"
$ipStart,$ipEnd = $range.Split("-")
$ipCheck = "10.10.250.255"
($ipCheck -ge $ipStart) -AND ($ipCheck -le $ipEnd)
This is not working, if you give an IP 192.168.25.75 within range 192.168.25.0-192.168.25.255.