How would I shorten this please?

This topic contains 10 replies, has 4 voices, and was last updated by  Joel Sallow 3 months ago.

  • Author
    Posts
  • #99030

    Swatto
    Participant

    I am looking at a script on technet that I am going to modify to suit my needs, I have a question regarding how to shorten this please:

    $temp = get-ChildItem "env:\TEMP"    
    $temp2 = $temp.Value
    Remove-Item -Recurse  "$temp2\*" -Force -Verbose

    I do not want to have to use the second variable '$temp2' – can I somehow get the third line to parse the command:

    Remove-Item -Recurse "$temp.value\*"

    Thanks very much

  • #99033

    Don Jones
    Keymaster

    Remove-Item -Recurse "$($temp.value)\*"

    That's called a _subexpression_.

  • #99036

    Olaf Soyk
    Participant

    What is "env:\TEMP"? Typo? Does this really work? Why don't you do

    Get-ChildItem -Path "$ENV:TEMP" | Remove-Item -Recurse -Force
  • #99046

    Swatto
    Participant

    Thanks very much for the replies, it does work Olaf but your method is a lot better, I will use that 🙂

  • #99055

    Joel Sallow
    Participant

    Env: is a PSDrive that can access the environment variables. Try Get-ChildItem 'Env:\' — Get-ChildItem can iterate through multiple PSProviders, including the environment variables, certificate store ('Cert:\'), and several others.

    So, really, both $env:TEMP and Env:\Temp are equally valid ways of accessing the environment variables, and it's mostly a matter of preference.

    Additionally, the quotation marks aren't really needed since you're referencing a string variable anyway:

    Get-ChildItem -Path $env:TEMP | 
        Remove-Item -Recurse -Force
  • #99070

    Swatto
    Participant

    Thanks very much – well I have finished making modifications and tidying up the script I found on technet to cleanup a Windows image before Sysprep, hopefully some will find it useful:

    Start-Transcript -Path "$Env:USERPROFILE\Cleanup-BeforeSysprep.txt" -Force
    
    # Variables
    $Temp = "$ENV:TEMP"   
    $WinTemp = "$ENV:SystemDrive\Windows\Temp\*"     
    $CBS = "$ENV:SystemDrive\Windows\Logs\CBS\" 
    $SWTools = "$ENV:SystemDrive\SWTools\*"
    $Drivers = "$ENV:SystemDrive\Drivers\*"
    $SWSetup = "$ENV:SystemDrive\SWSetup\*"
    $Downloads = "$ENV:SystemDrive\Users\Administrator\Downloads\*"
    $Prefetch = "$ENV:SystemDrive\Windows\Prefetch\*"
    $DownloadedUpdates = "$ENV:SystemDrive\Windows\SoftwareDistribution\Download\*"
    
    $VariableList = @($DownloadedUpdates, $Temp, $WinTemp, $CBS, $SWTools, $Drivers, $SWSetup, $Downloads, $Prefetch)
    
    # Removing Files
    ForEach ($Variable in $VariableList)
    {
        "Removing Files - $Variable - {0:N2} MB" -f ((Get-ChildItem -Path $Variable -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB)
        Remove-Item -Path $Variable -Recurse -Verbose -ErrorAction SilentlyContinue
        "After Deletion - $Variable - {0:N2} MB" -f ((Get-ChildItem -Path $Variable -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB)
        Write-Host "--------------------------------------------------------------------"
    }
    
    # Removing - IE Data
    Write-Host "Removing - Internet Explorer Data" -ForegroundColor DarkYellow
    Start-Process RunDll32.exe -ArgumentList "InetCpl.cpl ClearMyTracksByProcess 255" -Wait
    
    # Removing Files - Recycle Bin
    Write-Host "Removing Files - Recyle Bin" -ForegroundColor DarkYellow
    (New-Object -ComObject Shell.Application).NameSpace(0xa).items() | ForEach-Object { Remove-Item $_.Path -Force -Recurse }
    
    # Running - Disk Cleanup   
    Write-Host "Starting - Windows Disk Cleanup Tool" -ForegroundColor DarkYellow   
    Start-Process cleanmgr.exe -ArgumentList /SAGESET:50 -Wait
    Start-Process cleanmgr.exe -ArgumentList /SAGERUN:50 -Wait 
    
    Write-Host "Cleanup Complete" -ForegroundColor Green
    
    Stop-Transcript
  • #99075

    Joel Sallow
    Participant

    Looks pretty nice! Very handy to have around, for sure. I see a few things that maybe could be reconsidered here and there, mostly some insanely long lines that really detract from the tradability of the script, and the unusual manner of manually putting a list of variables into an array.

    Some minor modifications later, and me getting a bit carried away...

    [CmdletBinding()]
    param(
        [Parameter(Position = 0)]
        [ValidateScript(
            { Test-Path -Path $_ -IsValid }
        )]
        $TranscriptPath = "$Env:USERPROFILE\Cleanup-BeforeSysprep.txt"
    )
    begin {
        Start-Transcript -Path $TranscriptPath -Force
    
        # Variables
        $FoldersToClean = @(
            "$Env:TEMP"   
            "$Env:SystemDrive\Windows\Temp\*"     
            "$Env:SystemDrive\Windows\Logs\CBS\" 
            "$Env:SystemDrive\SWTools\*"
            "$Env:SystemDrive\Drivers\*"
            "$Env:SystemDrive\SWSetup\*"
            "$Env:SystemDrive\Users\Administrator\Downloads\*"
            "$Env:SystemDrive\Windows\Prefetch\*"
            "$Env:SystemDrive\Windows\SoftwareDistribution\Download\*"
        )
    }
    process {
        # Removing Files
        foreach ($Folder in $FoldersToClean) {
            $FolderSize = Get-ChildItem -Path $Folder -Recurse -ErrorAction SilentlyContinue | 
                Measure-Object -Property Length -Sum -ErrorAction Stop |
                ForEach-Object -MemberName Sum {$_ / 1MB}
    
            Write-Information "Removing Files from $Folder - $FolderSize MB" -Tags 'CleanupInfo'
            Remove-Item -Path $Folder -Recurse -Verbose -ErrorAction SilentlyContinue
    
            $FolderSize = Get-ChildItem -Path $Folder -Recurse -ErrorAction SilentlyContinue | 
                Measure-Object -Property Length -Sum -ErrorAction Stop |
                ForEach-Object -MemberName Sum {$_ / 1MB}
                
            Write-Information "After Deletion from $Folder - $Folder MB" -Tags 'CleanupInfo'
        }
    
        # Removing - IE Data
        Write-Verbose "Removing - Internet Explorer Data"
        Start-Process -FilePath 'RunDll32.exe' -ArgumentList "InetCpl.cpl ClearMyTracksByProcess 255" -Wait
    
        # Removing Files - Recycle Bin
        Write-Verbose "Removing Files - Recyle Bin"
        (New-Object -ComObject Shell.Application).NameSpace(0xa).Items() | 
            Remove-Item -Path {$_.Path} -Force -Recurse
    
        # Running - Disk Cleanup   
        Write-Verbose "Starting - Windows Disk Cleanup Tool"
        Start-Process -FilePath 'cleanmgr.exe' -ArgumentList /SAGESET:50 -Wait
        Start-Process -FilePath 'cleanmgr.exe' -ArgumentList /SAGERUN:50 -Wait 
    
        Write-Information "Cleanup Complete" -Tags 'CleanupInfo'
    }
    end {
        Stop-Transcript
    }
  • #99084

    Swatto
    Participant

    Thanks so much, that looks so much better, I can learn a lot from your improvements.

  • #99094

    Swatto
    Participant

    I have just tried the script but I am getting 'Input name "Sum" cannot be resolved to a method and the transcript is not showing the size of the folder.

    Thanks very much for your continued help on this 🙂

  • #99100

    Swatto
    Participant

    I have fixed it but not sure if it is the right approach:

    [CmdletBinding()]
    param(
        [Parameter(Position = 0)]
        [ValidateScript(
            { Test-Path -Path $_ -IsValid }
        )]
        $TranscriptPath = "$Env:USERPROFILE\Cleanup-BeforeSysprep.txt"
    )
    begin {
        Start-Transcript -Path $TranscriptPath -Force
    
        # Variables
        $FoldersToClean = @(
            "$Env:TEMP"   
            "$Env:SystemDrive\Windows\Temp\*"     
            "$Env:SystemDrive\Windows\Logs\CBS\" 
            "$Env:SystemDrive\SWTools\*"
            "$Env:SystemDrive\Drivers\*"
            "$Env:SystemDrive\SWSetup\*"
            "$Env:SystemDrive\Users\Administrator\Downloads\*"
            "$Env:SystemDrive\Windows\Prefetch\*"
            "$Env:SystemDrive\Windows\SoftwareDistribution\Download\*"
        )
    }
    process {
        # Removing Files
        foreach ($Folder in $FoldersToClean) {
            $FolderSize = (Get-ChildItem -Path $Folder -Recurse -ErrorAction SilentlyContinue | 
                Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB
    
            Write-Information "Removing Files from $Folder - $([math]::Round($FolderSize,2)) MB" -Tags 'CleanupInfo'
            Remove-Item -Path $Folder -Recurse -Verbose -ErrorAction SilentlyContinue
    
            $FolderSize = (Get-ChildItem -Path $Folder -Recurse -ErrorAction SilentlyContinue | 
                Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB
                
            Write-Information "After Deletion from $Folder - $([math]::Round($FolderSize,2)) MB" -Tags 'CleanupInfo'
        }
    
        # Removing - IE Data
        Write-Verbose "Removing - Internet Explorer Data"
        Start-Process -FilePath 'RunDll32.exe' -ArgumentList "InetCpl.cpl ClearMyTracksByProcess 255" -Wait
    
        # Removing Files - Recycle Bin
        Write-Verbose "Removing Files - Recyle Bin"
        (New-Object -ComObject Shell.Application).NameSpace(0xa).Items() | 
            Remove-Item -Path {$_.Path} -Force -Recurse
    
        # Running - Disk Cleanup   
        Write-Verbose "Starting - Windows Disk Cleanup Tool"
        Start-Process -FilePath 'cleanmgr.exe' -ArgumentList /SAGESET:50 -Wait
        Start-Process -FilePath 'cleanmgr.exe' -ArgumentList /SAGERUN:50 -Wait 
    
        Write-Information "Cleanup Complete" -Tags 'CleanupInfo'
    }
    end {
        Stop-Transcript
    }
  • #99126

    Joel Sallow
    Participant

    Yep, that's probably the easiest way to go about it, for sure. You could also potentially do a more complicated Select-Object and then a ForEach-Object, but really that's just overcomplicating it at that point, haha! 🙂

You must be logged in to reply to this topic.