Split directory path powershell - powershell

I want to split directory path using power shell. My full path is D:\data\path1\path2\abc.txt and i want to split it to path2\abc.txt.
Can someone let me know how can I do that.

$last2parts = "D:\data\path1\path2\abc.txt".Split("\") | Select-Object -Last 2
$last2parts -join "\"
In reply to your comment on another solution try this. Just remove your constant d:\data\path1. Then perform the split
$last2parts = "D:\data\path1\path2\abc.txt".Replace("D:\data\path1","")
$last2parts =$last2parts.Split("\") | Select-Object -Last 2
$last2parts -join "\"
Or try perhaps this if you want everything after D:\data\path1
$lastparts = "D:\data\path1\path2\abc.txt".Replace("D:\data\path1","")
$lastparts =$lastparts.Split("\")
$lastparts -join "\"

$PathAsString = "D:\data\path1\path2\abc.txt"
[System.IO.Path]::Combine($(Split-Path -leaf $(Split-Path $PathAsString)),$(Split-Path -leaf $PathAsString))
Uses the system's delimiter rather than specifying Windows' '\' character.
Honestly if I knew this was only ever going to run on Windows systems I'd go with #ChiliYago's answer since you can't put the path delimiter character in a file or directory name like you can in Linux.

Sorry for the super late post! I think you may have got the fix. But here is something you can try.
You can try using the substring() function as well.
$fullPath = "D:\data\path1\path2\abc.txt"
$rootPath = "D:\data\path1\"
$filePath = $fullPath.substring($rootPath.length, ($fullPath.length - $rootPath.length) )
Something like this may help you.

Here on Stack Overflow when you ask a question, please post some code that you've tried already and the results you're getting. We help you with code you've already tried, we aren't here to write it for you (:
However... I would start here: Link
That will get you started. You can also do the following in a console to get some info on the command Split-Path
Get-Help Split-Path -Example
After you put something together on your own, you can edit your post to include what you've tried and then you will be more likely to get an accurate response for your particular situation. Good luck and good coding!

Related

Powershell - Get part of a file path up to a point from a CSV

Need some help with a substring please? I have a csv which contains file paths in column A.
These paths have .foo at the end (appended from the original query).
Is there a way to use a substring (or something else) which will search the path\text and return the content up until this point for example
C:\test folder\Folder1\Test 2\filename.abc(foo)
and return
C:\test folder\Folder1\Test 2\filename.abc
I dont really have any sample code as Im just starting out - thanks.
I am not going to write this for you but I will give you an example and some things to read to get you going. Make sure to take the tour https://stackoverflow.com/tour.
Jump in to your code by writing some code and then come ask again. These articles here will help you with what you want.
https://devblogs.microsoft.com/scripting/trim-your-strings-with-powershell/
or
https://adamtheautomator.com/powershell-split-path/
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_split?view=powershell-7.2
Here is an example I made for you
$file = (Get-ChildItem C:\Temp\dnd.txt | Select-Object -ExpandProperty name).Split('.')[0]
There are a ton of ways to do what you are asking and my example is not even a start. Write some code, define your goals and come ask again.
a different example
https://devblogs.microsoft.com/scripting/two-simple-powershell-methods-to-remove-the-last-letter-of-a-string/
$file = Get-ChildItem C:\Temp\dnd.txt | Select-Object -ExpandProperty name
$file = $file.Substring(0,$file.Length - 3)
$file
Corrected again. Please understand there are better ways to do what I did and you really need to explain what you want better.
Last one :)
Let's assume you have a file called example.csv in the c:\temp folder.
Inside the file example.csv are a bunch of paths with something you need to strip of the end and then output the results.
Contents of example.csv
head
c:\temp\fileafoo
c:\temp\filebfoo
c:\temp\filestuffcfoo
The code
$paths = $null
$paths = Import-Csv C:\temp\example.csv | ForEach-Object{
$var = $null
$var = $_.head
[PSCustomObject]#{
Corrected = $var.substring(0,$var.length - 3)
}
}
$paths
Results are
Corrected
---------
c:\temp\filea
c:\temp\fileb
c:\temp\filestuffc
And you can export this with $paths | Export-csv c:\temp\result.csv -NoTypeInformation

How to download multiple files with powershell

Okay, so, here is what I ended up editing from my original answer. Kudos to #Matt for pointing out that I should be more descriptive with my answer and explain clearly what my edits were so that other users might be able to benefit from my answer in the futre. Users like #Matt are a great part of this community and put emphasis on keeping the standards high here.
The first thing I edited/added is the ability to delete the previous log from each run. Since this script will be scheduled it is important to remove the previous logs in order to prevent utilizing up too much disk space. This can be noted under the comment: "delete log files from prev run"
# delete log files from prev Run
Remove-Item C:\alerts\logs\*.*
The next thing I edited/added is the ability to switch between host names. I did this to prevent the overwriting of the files. You can see this under the comment "change filename in order to prevent overwriting of log file". I accomplished this by checking the index of "$url" in the foreach loop, and checked to see if it was at the position where I needed to change the host name. I suspect there was a much more intuitive way to do this and I would just love it if someone chimed in with a better way to do this as its driving me crazy that I don't know a better way. It should be noted that there are a total of 44 urls where I'm downloading from, hence the magic numbers (11, 22, 33) where I change the host name. Again, if you know a better way please don't hesitate to let me know.
If ($urls.IndexOf($url) -eq 11){
$currentDir = "goxsd1704"
}
ElseIf ($urls.IndexOf($url) -eq 22){
$currentDir = "goxsd1705"
}
ElseIf ($urls.IndexOf($url) -eq 33){
$currentDir = "goxsd1706"
}
The next thing I edited/added, thanks to #Matt for the recommendation is the try catch blocks which are clearly noted in the code. I should of had these to start with as by not having them before I was assuming that the script was always going to work. Rookie mistake and point taken.With that being said, these are all my edits. The code is working fine, but improvement is always possible. Thank you for your time and answers.
# set date
$date = Get-Date -UFormat "%Y-%m-%d-%H_EST"
# delete log files from prev Run
Remove-Item C:\alerts\logs\*.*
# setup download links
$urls = "http://subdomain.domain.com:portnumber/LogA/API_DBG_CS_Logs/dbg_a.$date.log"
function DownloadFMOSLogs()
{
try
{
# assign working dir to currentDir
$currentDir = "goxsd1703"
# instantiate web-client.
$wc = New-Object System.Net.WebClient
# loop through each url
foreach ($url in $urls)
{
# change filename to prevent overwriting of log file
If ($urls.IndexOf($url) -eq 11){
$currentDir = "goxsd1704"
}
ElseIf ($urls.IndexOf($url) -eq 22){
$currentDir = "goxsd1705"
}
ElseIf ($urls.IndexOf($url) -eq 33){
$currentDir = "goxsd1706"
}
# get file name
$fileName = $url.SubString($url.LastIndexOf('/')+1)
# create target file name
$targetFileName = "C:\alerts\logs\" + $currentDir + "_" + $fileName
$wc.DownloadFile($url, $targetFileName)
Write-Host "Downloaded $url to file location $targetFileName"
}
} catch [System.Net.WebException],[System.IO.IOException]
{
"An error occurred. Files were not downloaded."
}
}
DownloadFMOSLogs
Write-Host ""
Write-Host "Download of application log files has successfully completed!"
Invoke-WebRequest is a good way in Powershell to download files and the OutFile parameter will put this straight to disk, docs are here.
Have a go with Invoke-WebRequest -Uri $link -OutFile $targetFileName
You have a couple of problems and an issue or two.
$urls is not an array like you think it is. It is actually one whole string. Try something like this instead:
$urls = "http://subdomain.domain.com:port/LogA/API_DBG_CS_Logs/dbg_a.$date.log",
"http://subdomain.domain.com:port/LogA/API_DBG_CS_Logs/dbg_b.$date.log"
The variable will expand in that string just fine. The issue before is that you were concatenating the string starting from the first part because of the order of operations. When you add an array to a string on the left hand side the array gets converted to a space delimited string. Have a look at a smaller example which is exactly what you tried to do.
"hello" + 2,2 + "there"
You could have made what you had work if you wrapped each one in a set of brackets first.
("hello" + 2),(2 + "there")
This code might make sense elsewhere but as others have pointed out you have a useless loop about lines in a file. foreach($line in Get-Content .\hosts.txt). If you don't use it get rid of it.
You don't really use $targetDir to its full potential. If you are going to use the working directory of the script at least use some absolute paths. Side note the comments don't really match what is happening which is likely related to 2. above
# preprend host to file name to keep file names diff.
$targetFilePath = [io.path]::combine($pwd,"test.txt")
# download the files.
$wc.DownloadFile($link, $targetFilePath)
You should try and make that unique somehow since the files will overwrite eachother as you have it coded.
I would also wrap that in a try block in case the download fails and you can report properly on that. As of now you assume it will work every time.

Powershell - net use doesn't work with variables

I'm trying to get a script running that maps network drives at login. Generally, I use get-content with | convertfrom-stringdata to put my parameters (drive letter and path) in a hash.
My problem is the following:
net use /persistent:no $driveletter $networkpath
results with an error. When I replace $networkpath with the actual path (\\server\share\folder), it works.
Does anyone know what to do there? Help is greatly appreciated.
If any information is missing, I'll add it as soon as I can!
Greetings,
Blaargh
EDIT: more code for better understanding of problem
$hash = get-content C:\temp\file.txt | convertfrom-stringdata
foreach ($keys in $hash.keys) {
$hashtwo = $hash.$keys -split ("=")
net use /persistent:no $hashtwo[1] $hashtwo[0]
}
My textfile looks like this:
key = \\\\server\\share\\folder =G:
PetSerAl found the solution:
#blaargh Add Write-Host "'$($hashtwo[1])' '$($hashtwo[0])'" to be sure, that variables does not have extra space somewhere.

Powershell Check newest log file for latest entry containing error

I know I am missing something small. But, I am overlooking something. I want the script to look in a specific path for the newest log file, and check the last line of the log file, and if it contains a specific error, have it email a notification. It finds the newest file properly, but doesn't seem to be giving me the output of the last line. Thoughts on what silly thing I missed?
Set-Location -Path "\\COMPUTER\C$\application\logs"
$latest = Get-ChildItem | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$latest.name
$lastentry = Get-Content $latest | Select-object -last 1
if ($lastentry -like "ERROR: Access violation at address*") {
$strFromAddress = "monitoring#acertaindomain.com"
$strToAddress = "LotsOfPeople#acertaindomain.com"
$strMessageSubject = "Your log has errors"
$strMessageBody = "Bad stuff is happening"
$strSendingServer = "mail.acertaindomain.com"
}
I'm such an idiot. I thank you guys for the input. All those email tags and I completely forgot the actual command to send the bloody email.
I just brain farted in the worst way. But also, your added logic helped proof it. I of course realized I was jacking up something silly when write-output displayed what I was looking for.
Remember kids, it's all great to set variables. But don't forget to do something with them. lol

Change path separator in Windows PowerShell

Is it possible to get PowerShell to always output / instead of \? For example, I'd like the output of get-location to be C:/Documents and Settings/Administrator.
Update
Thanks for the examples of using replace, but I was hoping for this to happen globally (e.g. tab completion, etc.). Based on Matt's observation that the separator is defined by System.IO.Path.DirectorySeparatorChar which appears in practice and from the documentation to be read-only, I'm guessing this isn't possible.
It's a good question. The underlying .NET framework surfaces this as System.IO.Path.DirectorySeparatorChar, and it's a read/write property, so I figured you could do this:
[IO.Path]::DirectorySeparatorChar = '/'
... and that appears to succeed, except if you then type this:
[IO.Path]::DirectorySeparatorChar
... it tells you that it's still '\'. It's like it's not "taking hold". Heck, I'm not even sure that PowerShell honours that particular value even if it was changing.
I thought I'd post this (at the risk of it not actually answering your question) in case it helps someone else find the real answer. I'm sure it would be something to do with that DirectorySeparatorChar field.
Replace "\" with "/".
PS C:\Users\dance2die> $path = "C:\Documents and Settings\Administrator"
PS C:\Users\dance2die> $path.Replace("\", "/")
C:/Documents and Settings/Administrator
You could create a filter (or function) that you can pipe your paths to:
PS C:\> filter replace-slash {$_ -replace "\\", "/"}
PS C:\> Get-Location | replace-slash
C:/