1

Building on the code from this answer, I tried this to find all .url files which include http://kfhntwvap347, but I also tried http://kfhntwvap347:8080/consense/ in $urlParts knowing that there is such a .url file, but it always shows no results.

The intent is to find such URL and then to replace it.

# The literal URL parts to find, either prefixes or substrings.
$urlParts = 'http://kfhntwvap347'

$regex = '^URL=({0})' -f (
  $urlParts.ForEach({ 
    $escaped = [regex]::Escape($_) # Escape for literal matching, if needed.
    if ($escaped -match '^https?:') { $escaped } 
    else                            { '.*' + $escaped } # match anywhere in the URL
  }) -join '|'
)

# Search all *.url files in the subtree of D:\waveprod\DMS for the URL parts
# and output the full paths of matching files.
# Outputs to the screen and saves to a file.

$foundPaths = Get-ChildItem -Force -Recurse D:\waveprod\DMS -Filter *.url | 
  Select-String -Pattern $regex -List | 
  ForEach-Object {
    $path = $_.Path
    Write-Output $path
    $path
  }

# Display a message based on whether results were found or not
if ($foundPaths.Count -gt 0) {
  Write-Host "Results found!"
} else {
  Write-Host "No results found."
}

# Save the found paths to a text file in D:\powershell\
$foundPaths | Out-File -FilePath 'D:\powershell\found_paths.txt'

enter image description here

I would expect that it finds such files but I tried many variations without success.

6
  • 2
    With $urlParts = 'http://kfhntwvap347', the code does match a .url file with the content shown in your screenshot in my tests. Please try to provide a minimal reproducible example. Commented Jan 28, 2024 at 23:22
  • 1
    just checked it again, it is PSVersion 5.1.143 Desktop from PowerShell. Strange that it does not find anything Commented Jan 29, 2024 at 1:40
  • 2
    Like mklement0, I also tested your code and successfully found the URL file, so I don't have a solution but wanted to point out a couple minor improvements to your code. In your regex if statement, you're checking if it matches ^http?:'. This regex matches either http: or htt:. I'm assuming what you want is ^https?:, which matches http: or https:. Also in your ForEach loop you output the $path twice and also assigning $_.path to $path is unnecessary, just use this: ForEach-Object { $_.path } Commented Jan 29, 2024 at 5:56
  • Good catch, @jeremywat, and good points. I've fixed the ^http?: part to avoid confusion: It was simply a copy-paste error from the linked answer. Commented Jan 29, 2024 at 14:00
  • 1
    @iRon: That is good advice in general, but wouldn't really help here (except perhaps to use (New-Object -ComObject WScript.Shell).CreateShortcut("d:\path\to\some.url").TargetPath to more robustly extract the URL string). The linked post (to which this question is a follow-up) makes the use case clearer: matching one of multiple arbitrary URL prefixes and substrings, for which text processing is the right approach, and regexes allow for the most concise implementation. Commented Jan 29, 2024 at 14:11

1 Answer 1

0

I find using type casting (if available) will help when working with some type of complex objects.

C:\> [uri]'http://kfhntwvap347:8080/consense/'


AbsolutePath   : /consense/
AbsoluteUri    : http://kfhntwvap347:8080/consense/
LocalPath      : /consense/
Authority      : kfhntwvap347:8080
HostNameType   : Dns
IsDefaultPort  : False
IsFile         : False
IsLoopback     : False
PathAndQuery   : /consense/
Segments       : {/, consense/}
IsUnc          : False
Host           : kfhntwvap347
Port           : 8080
Query          :
Fragment       :
Scheme         : http
OriginalString : http://kfhntwvap347:8080/consense/
DnsSafeHost    : kfhntwvap347
IdnHost        : kfhntwvap347
IsAbsoluteUri  : True
UserEscaped    : False
UserInfo       :

So by comparing the property Authority with Host (in this case filtering), you can easily tell if the URL-file needs to be handled.

[uri]'http://kfhntwvap347:8080/consense/',
[uri]'http://kfhntwvap347/consense/' |
  where {$_.Host -ne $_.Authority} |
    select AbsoluteUri

AbsoluteUri
-----------
http://kfhntwvap347:8080/consense/

In this case we also need a good way to handle ini-files. PsIni from PSGallery is a good bet.

Install-Module PsIni

Get-ChildItem .\*.url | select Name,
  @{ l = 'URI'; e = {[uri](Get-IniContent $_).InternetShortcut.Url} } |
    where {$_.URI.Host -ne $_.URI.Authority}

Edit: I didn't notice the property IsDefaultPort before which makes to selection even easier.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.