question

Ed7 avatar image
1 Vote"
Ed7 asked Ed7 answered

Relative path powershell

Hello,

I need to construct a relative path from the directory at the top of the tree...
For example, if the file in question lives at absolute path C:\Users\MyUsername\Desktop\test.txt, and I decide that the root directory is C:\Users\MyUsername, the relative path would be Desktop\test.txt, which is what should be stored in the CSV.

I am going to check for several folders and its contents
In one variable can I use such as this: $variabel1 = "<pathtofolder1>","<pathtofolder2>","<pathtofolder3>"

Could you tell how I can do it whithin my current script please?

Here is my current powershell script:

$root = "C:\Users\"
$hasher = [System.Security.Cryptography.SHA256]::Create()
$AllFiles = @()


foreach ($file in get-childitem $root -recurse | Select-Object FullName, Directory, Name, PSIsContainer, Length, CreationTime, LastAccessTime, LastWriteTime, Path)

{
$acl = get-acl $file.fullname | select-object path,owner,accesstostring,group
$obj = new-object psObject
$obj | Add-Member -membertype noteproperty -name FilePathandName -Value $file.FullName
$obj | Add-Member -MemberType noteproperty -Name Path -Value $file.path
$obj | Add-Member -membertype noteproperty -name Name -Value $file.Name
$obj | Add-Member -MemberType noteproperty -Name Hash -Value $builder.ToString()
$obj | Add-Member -membertype noteproperty -name CreationTime -Value $file.CreationTime
$obj | Add-Member -MemberType noteproperty -Name LastAccessTime -Value $file.LastAccessTime
$obj | Add-Member -MemberType noteproperty -Name LastWriteTime -Value $file.LastWriteTime
$obj | Add-Member -MemberType noteproperty -Name Owner -Value $acl.owner
$obj | Add-Member -MemberType noteproperty -Name Group -Value $acl.group
$AllFiles += $obj

if(!$file.PsIsContainer)
{
$inputStream = New-Object IO.StreamReader $file.fullname
$hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
$inputStream.Close()

$builder = New-Object System.Text.StringBuilder
$hashBytes | Foreach-Object { [void] $builder.Append($_.ToString("X2")) }
$obj | Add-Member -MemberType noteproperty -Name MD5Hash -Value $builder.ToString()
}
}

$AllFiles += $obj


$AllFiles |Export-Csv $report –NoTypeInformation

windows-serverwindows-server-powershellpower-query-not-supportedoffice-scripts-excel-dev
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ClementBETACORNE avatar image
0 Votes"
ClementBETACORNE answered

Hello,

You can use substring to achieve what you want, for example before writing the path attribute on your custom object you can do that :

 $Root = "C:\Users\"
    
 $items = Get-ChildItem -Path $Root -Recurse -File
    
 foreach($item in $items) {
     $relativePath = $item.FullName.Substring($Root.Length)
     $obj | Add-Member -MemberType noteproperty -Name Path -Value $relativePath
 }

Regards,

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Ed7 avatar image
0 Votes"
Ed7 answered Ed7 edited

HI @ClementBETACORNE,

Using the info you provided I can get the relative path, however it does keep one relative path using diferent paths.

154746-image.png



image.png (27.7 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

MotoX80 avatar image
0 Votes"
MotoX80 answered

Your script is missing the $report variable, and you reference $builder before you create the object.
Your Select-object references a path value, but Get-Childitem objects do not have a path value.
You add the obj to AllFiles before you do the container processing.

Give this script a try. It excludes the username from the relative path.

 $root = "C:\Users\"
 $report = "c:\temp\files.csv"
 $hasher = [System.Security.Cryptography.SHA256]::Create()
 $AllFiles = @()
    
    
 foreach ($file in get-childitem $root -recurse | Select-Object FullName, Directory, Name, PSIsContainer, Length, CreationTime, LastAccessTime, LastWriteTime)      # no path  , Path)
    
 {
     $file.fullname
     $acl = get-acl $file.fullname | select-object path,owner,accesstostring,group
     $obj = new-object psObject
     $obj | Add-Member -membertype noteproperty -name FilePathandName -Value $file.FullName
     # file does not have a path value   $obj | Add-Member -MemberType noteproperty -Name Path -Value $file.path
     $rp = $file.FullName.Substring($root.length)               # omit C:\users
     if ($rp.IndexOf("\") -lt 0) {                              # are looking the user itself? 
         $rp = ""                                               # there is no relative path  
     } else {
         $rp = $rp.Substring($rp.IndexOf("\") + 1)              # pick whatever come after the first slash 
     }
     $obj | Add-Member -MemberType noteproperty -Name RelativePath -Value $rp
     $obj | Add-Member -membertype noteproperty -name Name -Value $file.Name
     #  builder????     $obj | Add-Member -MemberType noteproperty -Name Hash -Value $builder.ToString()
     $obj | Add-Member -membertype noteproperty -name CreationTime -Value $file.CreationTime
     $obj | Add-Member -MemberType noteproperty -Name LastAccessTime -Value $file.LastAccessTime
     $obj | Add-Member -MemberType noteproperty -Name LastWriteTime -Value $file.LastWriteTime
     $obj | Add-Member -MemberType noteproperty -Name Owner -Value $acl.owner
     $obj | Add-Member -MemberType noteproperty -Name Group -Value $acl.group
     # not here     $AllFiles += $obj
    
     if(!$file.PsIsContainer)
     {
         "It's a container"
         $inputStream = New-Object IO.StreamReader $file.fullname
         $hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
         $inputStream.Close()
    
         $builder = New-Object System.Text.StringBuilder
         $hashBytes | Foreach-Object { [void] $builder.Append($_.ToString("X2")) }
         $obj | Add-Member -MemberType noteproperty -Name MD5Hash -Value $builder.ToString()
     } else {
         $obj | Add-Member -MemberType noteproperty -Name MD5Hash -Value ""      # blank value because t does not apply 
     }
     $AllFiles += $obj                         # Add the object after all properties are built 
    
 }
    
 #  this would add the last obect twice.     $AllFiles += $obj
    
    
 $AllFiles |Export-Csv $report –NoTypeInformation
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

joseantoniosilva avatar image
0 Votes"
joseantoniosilva answered

@Ed7
Not sure what you looking for with that relative path, but ended up using your script to create a script for me too:
154875-md5report.png


 param (
     $root = "C:\Users\$env:USERNAME\",
     $report = "$Env:TEMP\report-$env:USERNAME.csv"
 )
    
 $hasher = [System.Security.Cryptography.SHA256]::Create()
    
 get-childitem $root -recurse | 
     Select-Object FullName, Name, PSIsContainer, Length, CreationTime, LastAccessTime, LastWriteTime | 
     foreach { 
         $file = $_
         $acl = get-acl $file.fullname | select-object owner,group #,accesstostring
         #merge attributes
         $acl | get-member -MemberType NoteProperty | %{ Add-Member -InputObject $file -NotePropertyName $_.Name -NotePropertyValue $acl.$($_.Name)}
            
         # add relative path
         Add-Member -InputObject $file -NotePropertyName Path -NotePropertyValue $file.FullName.Replace($root,'') 
        
         # MD5Hash
         $md5 = if(!$file.PsIsContainer) {
             $inputStream = New-Object IO.StreamReader $_.fullname
             $hashBytes = $hasher.ComputeHash($inputStream.BaseStream)
             $inputStream.Close()
    
             $builder = New-Object System.Text.StringBuilder
             $hashBytes | Foreach-Object { [void] $builder.Append($_.ToString("X2")) }
             $builder.ToString()
         }
         else {
             ''
         }
         Add-Member -InputObject $file -NotePropertyName MD5Hash -NotePropertyValue $md5
         $file
     } | 
     Export-Csv -NoTypeInformation -Path $report
    
 Write-host "Exported to $report" -ForegroundColor Green
 #test
 gc $report | convertfrom-csv | sort path | select name,length, MD5Hash, owner, path | ft










md5report.png (92.6 KiB)
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Ed7 avatar image
0 Votes"
Ed7 answered

Thank you guys for your help. It really worked as expected. Much appreciatted.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.