How would I shorten this please?

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

Remove-Item -Recurse “$($temp.value)*”

That’s called a subexpression.

What is “env:\TEMP”? Typo? Does this really work? Why don’t you do

Get-ChildItem -Path “$ENV:TEMP” | Remove-Item -Recurse -Force

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

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

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

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
}

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

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 :slight_smile:

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
}

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! :slight_smile: