defrag script for sysinternal contig

Page 2 of 5 FirstFirst 1234 ... LastLast

  1. Posts : 745
    Windows 10/11
       #11

    This should get you started:

    Code:
    Param (
      $Target = 'C:\Movies\*.*',
      $MinFrags = [Int]'4',
      $ClearLog = 1
    )
    
    $Title = 'Edefrag'
    $host.ui.RawUI.WindowTitle = $Title
    $TempDir = "$env:TEMP"
    $Temp1 = "$TempDir\$Title-1.tmp"
    $Temp2 = "$TempDir\$Title-2.tmp"
    $LogFile = "$PSScriptRoot\$Title.txt"
    $PSDefaultParameterValues['Out-File:Encoding'] = 'default'
    
    If (-Not(Test-Path "$PSScriptRoot\Contig.exe")) {
      If ((Get-Command 'Contig.exe' -ErrorAction SilentlyContinue) -eq $null) 
      { 
        Write-Host 'Contig.exe not found in script directory or search path'
        Write-Host 'Download it from https://docs.microsoft.com/en-us/sysinternals/downloads/contig'
        Exit
      }
    }
    
    If ($ClearLog) {
      If (Test-Path $LogFile) {
        Remove-Item $LogFile
      }
    }
    
    $Language = Get-Culture
    
    If ($Language -eq 'en-US') {
      $Str01 = 'Allocated Size'
      $Str02 = 'Allocated Size'
      $Msg01 = 'Searching for fragmented files...'
      $Msg02 = "Analyze the files with minimum $MinFrags fragments..."
    }
    
    If ($Language -eq 'it-IT') {
      $Str01 = 'Dimensione allocata'
      $Str02 = 'Dimensioni allocate'
      $Msg01 = 'Ricerca di file frammentati...'
      $Msg02 = "Analizza i file con minimo $MinFrags frammenti..."
    }
    
    Write-Host $Msg01
    
    Cmd.exe /c "Chcp 1252 & Contig.exe -nobanner -a -s $Target >$Temp1"
    
    Write-Host $Msg02
    
    Function GetFragSizes($FileName){
      If (Test-Path $FileName) {
        fsutil file layout $FileName >$Temp2
        ForEach ($Line in Get-Content $Temp2) {
          If (($Line -match $Str01) -Or ($Line -match $Str02)) {
            $Size = $Line.Split(':')[1]
            $Sizes = $Sizes + $Size + ' ' 
          }
        }
        Return $Sizes
      }
      Else {
        Return 'File cannot be found'
      }
    }
    
    [System.IO.File]::ReadLines($Temp1, [System.Text.Encoding]::Default) | ForEach-Object {
      $Line = $_
      If ($Line -match ' fragments') {
        $Line = ($Line -Replace ' fragments','~fragments')
        $Items = $Line.Split(' ')
        $FragItem = $Items[$Items.Count-1]
        $FragCount = [Int]$FragItem.Split('~')[0]
        If ($FragCount -ge $MinFrags) {
          $FileName = $Line.Substring(0,$Line.Length - $FragItem.Length - 7)
          Echo $FileName
          $FragSizes = GetFragSizes($FileName)
          $Result = "$FileName | $FragCount | $FragSizes"
          Write-Host $Result
          Write-Output $Result >>$LogFile
        }
      }
    }
    Last edited by LesFerch; 15 Jul 2021 at 21:56.
      My Computer


  2. Posts : 745
    Windows 10/11
       #12

    A few helpful starter notes about PowerShell...

    Literal strings are in single quotes. Example: $Title = 'Edefrag'
    Expandable strings are in double quotes. Example: $Temp1 = "$TempDir\$Title-1.tmp"

    When searching Google for help with PowerShell operators, you need to quote that item. For example, if you want help on the -match operator, search for: PowerShell "-match"

    Just about anything you want help doing in PowerShell is documented on docs.microsoft.com and/or stackoverflow.com
      My Computer


  3. Posts : 15,485
    Windows10
       #13

    LesFerch said:
    Thanks for the detailed breakdown. PowerShell is definitely the way to go.

    But I have to ask a bigger question... Is there really much benefit to be gained by defragmenting? 30 years ago when I defragmented a hard drive, it made a noticeable performance improvement. Today, I doubt it will help much. With my 9 year old laptop, I found that a complete wipe and fresh install of Windows 10 (which would naturally result in minimal fragments) made only a small improvement to overall performance. What made a HUGE difference in performance was replacing my HD with an SSD. If I were seeking any further improvements (short of buying a new computer) I would also look at increasing RAM (if possible), so disk accesses are minimized.

    There's also the issue that defragmenting an SSD is unnecessary (Should You Defrag an SSD? | Crucial.com) and uses up some of the flash memory's finite write cycles.

    Anyhow, assuming this will be targeted to an HD and not an SSD, the programming looks interesting. I'll have a go and get back to you.
    Yep - Windows 10 quietly defrags in background, and it is years since I have had to manually defrag a hard drive to improve performance.

    As you say, SSDs are the way to go. I have several devices and over time, I have replaced all with SSDs. I only use my old hdds as data backup drives where speed is unimportant.

    To me, defragging a hard drive is a solution to a problem that we no longer have.
      My Computer


  4. Posts : 250
    Windows 10 22H2
    Thread Starter
       #14

    LesFerch said:
    Thanks for the detailed breakdown. PowerShell is definitely the way to go.

    But I have to ask a bigger question... Is there really much benefit to be gained by defragmenting? 30 years ago when I defragmented a hard drive, it made a noticeable performance improvement. Today, I doubt it will help much. With my 9 year old laptop, I found that a complete wipe and fresh install of Windows 10 (which would naturally result in minimal fragments) made only a small improvement to overall performance. What made a HUGE difference in performance was replacing my HD with an SSD. If I were seeking any further improvements (short of buying a new computer) I would also look at increasing RAM (if possible), so disk accesses are minimized.

    There's also the issue that defragmenting an SSD is unnecessary (Should You Defrag an SSD? | Crucial.com) and uses up some of the flash memory's finite write cycles.

    Anyhow, assuming this will be targeted to an HD and not an SSD, the programming looks interesting. I'll have a go and get back to you.
    As I said above, this script is for special situations. It is useful for HDDs. For example I have a 4T external drive and it is not SSD. The cost is still high for large SSDs. I know that SSD does not have the same issues and therefore needs to be treated differently.

    - - - Updated - - -

    LesFerch said:
    This should get you started:

    Code:
    Param (
      $Target = 'C:\Movies\*.*',
      $MinFrags = [Int]'4',
      $ClearLog = 1
    )
    
    $Title = 'Edefrag'
    $host.ui.RawUI.WindowTitle = $Title
    $TempDir = "$env:TEMP"
    $Temp1 = "$TempDir\$Title-1.tmp"
    $Temp2 = "$TempDir\$Title-2.tmp"
    $LogFile = "$PSScriptRoot\$Title.txt"
    
    If ($ClearLog) {
      If (Test-Path $LogFile) {
        Remove-Item $LogFile
      }
    }
    
    $Language = Get-Culture
    
    If ($Language -eq 'en-US') {
      $Str01 = 'Allocated Size'
      $Msg01 = 'Searching for fragmented files...'
      $Msg02 = "Analyze the files with minimum $MinFrags fragments..."
    }
    
    If ($Language -eq 'it-IT') {
      $Str01 = 'Dimensioni allocate'
      $Msg01 = 'Ricerca di file frammentati...'
      $Msg02 = "Analizza i file con minimo $MinFrags frammenti..."
    }
    
    Write-Host $Msg01
    
    Cmd /c Contig -a -s $Target >$Temp1
    
    Write-Host $Msg02
    
    Function GetFragSizes($FileName){
      fsutil file layout $FileName >$Temp2
      ForEach ($Line in Get-Content $Temp2) {
        If ($Line -match $Str01) {
          $Size = $Line.Split(':')[1]
          $Sizes = $Sizes + $Size + ' ' 
        }
      }
      Return $Sizes
    }
    
    [System.IO.File]::ReadLines($Temp1) | ForEach-Object {
      $Line = $_
      If ($Line -match ' fragments') {
        $Line = ($Line -Replace ' fragments','~fragments')
        $Items = $Line.Split(' ')
        $FragItem = $Items[$Items.Count-1]
        $FragCount = [Int]$FragItem.Split('~')[0]
        If ($FragCount -ge $MinFrags) {
          $FileName = $Line.Substring(0,$Line.Length - $FragItem.Length - 7)
          $FragSizes = GetFragSizes($FileName)
          $Result = "$FileName | $FragCount | $FragSizes"
          Write-Host $Result
          Write-Output $Result >>$LogFile
        }
      }
    }
    I'm having a bit of a problem. I created a file with .ps1 extension but I don't know how to run it as administrator.

    - - - Updated - - -

    It does not return the size of the files

    Code:
    ...
    C:\Program Files\AMD\atikmdag_dce.log | 5 | 
    C:\Program Files\CrystalDiskInfo\CdiResource\themes\Default | 8 | 
    C:\Program Files\CrystalDiskInfo\CdiResource\themes\Simplicity | 8 | 
    ...
      My Computers


  5. Posts : 18,044
    Win 10 Pro 64-bit v1909 - Build 18363 Custom ISO Install
       #15

    Hello @einstein1969,

    einstein1969 said:
    I'm having a bit of a problem. I created a file with .ps1 extension but I don't know how to run it as administrator.

    You could add the following Command to your PowerShell Script so it launches as Elevated [ Administrator ] . . .

    Code:
    
    PowerShell -NoProfile -ExecutionPolicy Unrestricted -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Unrestricted -File ""PS_Script_Path&Name.ps1""' -Verb RunAs}";

    REPLACE PS_Script_Path&Name.ps1 with the ACTUAL PS Script Path and Name.



    ALTERNATIVELY, you can add Run as Administrator for PowerShell to the Context Menu [ Probably easiest ] . . .

    > How to Add 'Run as administrator' to PS1 File Context Menu in Windows 10



    I hope this helps.

    EDIT: I thought you might also find this useful . . .

    > How to Add or Remove 'Run as administrator' Context Menu in Windows 10
      My Computer


  6. Posts : 250
    Windows 10 22H2
    Thread Starter
       #16

    For some file don't work the fsutils

    Edefrag-2.tmp:
    Code:
    Errore:  Impossibile trovare il file specificato.
    I think there is the problem with codepage, but i'm not sure

    @Paul Black
    Thanks!
      My Computers


  7. Posts : 18,044
    Win 10 Pro 64-bit v1909 - Build 18363 Custom ISO Install
       #17

    Hello @einstein1969,

    einstein1969 said:
    @Paul Black
    Thanks!
    You are VERY welcome.
      My Computer


  8. Posts : 7,607
    Windows 10 Home 20H2
       #18

    einstein1969 said:
    I created a file with .ps1 extension but I don't know how to run it as administrator.
    In addition to Paul's suggestion, you may use VBScript to run it as an administrator.

    Code:
    Set l=CreateObject("Shell.Application"):If WScript.Arguments.length=0 Then
    l.ShellExecute"wscript.exe",""""&WScript.ScriptFullName&""""&" +","","RunAs",1
    Else
    Set X=CreateObject("WScript.Shell"):File="E:\Testing.ps1"
    X.run("powershell -executionpolicy bypass -File "&""""&File&"""")
    End if

    Replace "E:\Testing.ps1" with the actual file path. It works as a shortcut.
    I have used the same code in the following:
    Using CMD script and VBScript to control Windows Update
      My Computer


  9. Posts : 745
    Windows 10/11
       #19

    einstein1969 said:
    It does not return the size of the files
    Code:
    ...
    C:\Program Files\AMD\atikmdag_dce.log | 5 | 
    C:\Program Files\CrystalDiskInfo\CdiResource\themes\Default | 8 | 
    C:\Program Files\CrystalDiskInfo\CdiResource\themes\Simplicity | 8 | 
    ...
    I set my language to Italian and quickly saw the issue is that FSUtil displays two different strings for Allocated Size, depending on whether it's a small number or large number:

    Dimensione allocata
    Dimensioni allocate

    I have modified the posted code to check for both strings.
      My Computer


  10. Posts : 745
    Windows 10/11
       #20

    einstein1969 said:
    For some file don't work the fsutils

    Code:
    Errore:  Impossibile trovare il file specificato.
    I see that says "Cannot find the specified file". Two possible reasons come to mind:

    1. The file was deleted (e.g. temp file) or renamed between the time Contig scanned it and FSUtil was run.

    2. There are unusual permissions set on the file that cause it to be seen by Contig, but not by FSUtil.

    I added a file existence check in the FSUtill function. That should fix it. If not, let's look closer at the files causing that error.
    Last edited by LesFerch; 14 Jul 2021 at 08:59.
      My Computer


 

  Related Discussions
Our Sites
Site Links
About Us
Windows 10 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 10" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd
All times are GMT -5. The time now is 03:41.
Find Us




Windows 10 Forums