PowerShell Create empty folders

From Valve Developer Community
Jump to navigation Jump to search


Here is PowerShell script sample. (20.10.2021)
- It search all *_dir.vpk files from 1st subfolders (not deeper)
- Using those VPK files into vpk.exe program to "dump" list of files inside VPK
- Collecting all file directories from dump list and create empty folders into \hl2 folder, mimic directories like inside VPK

How to use it

Create file into game root folder (where is steam_appid.txt and/or hl2.exe), use notepad.exe or else text editor
and save file as... CreateFolders.ps1. Be sure file suffix is ps1 and not txt.
Copy script from below and paste in your file, save it.

Click file with mouse button 2 and choose "Run with PowerShell"
If new window pops-up with Title message "Powershell script running!", you have got it working!

If you can't see script Title message "Powershell script running!" in first place, you lack Windows administration access and windows security will block script, because of "security" reasons.
You can try another method.
In Windows search bar, type PowerShell, choose Run as Administration
Set your location to your game root folder, example cd "F:\Program Files (x86)\Steam\steamapps\common\left 4 dead"
Type these commands

Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process
.\CreateFolders.ps1


- Extra: dump VPK list of files in txt files, -dumpvpkfiles 1

.\CreateFolders.ps1 -dumpvpkfiles 1


Powershellscript1.jpg


<#
    Powershell script: Create Empty Folders using file paths inside VPK packs.
    - Version 20.10.2021

    This script is for HL2 games which use VPK files.
    Idea is mimic directory paths from inside VPK file to game folder.
    This way can remove error while browsing folders in HLMV.exe (Steam) Load Model...
#>


param([int] $dumpvpkfiles=0)

if ( $dumpvpkfiles -ne 0 )
{
    Write-Host "-'$dumpvpkfiles'"
}



$pwrshelllog = ".\powershell_script.log"

# Ben Newton - https://stackoverflow.com/a/38738942
Function Write-Log {
    [CmdletBinding()]
    Param(
    [Parameter(Mandatory=$False)]
    [ValidateSet("INFO","WARN","ERROR","FATAL","DEBUG")]
    [String]
    $Level = "INFO",

    [Parameter(Mandatory=$True)]
    [string]
    $Message,

    [Parameter(Mandatory=$False)]
    [string]
    $logfile
    )

    $Stamp = (Get-Date).toString("yyyy/MM/dd HH:mm:ss")
    $Line = "$Stamp $Level $Message"
    If($logfile) {
        Add-Content $logfile -Value $Line
    }
    Else {
        Write-Output $Line
    }
}





# Actual code start here

Write-Log -Message "`n-script started`n- version 20.10.2021`n-" -level INFO -logfile $pwrshelllog




Write-Host `
"`n`n`
********************************`
*  Powershell script running!  *`
*  - version 20.10.2021        *`
********************************`
`n`n"`
-ForegroundColor Green -BackgroundColor DarkBlue



# Check file(s), are we in right location


$steam_appid = "steam_appid.txt"

if( -not ( Test-Path -Path .\$steam_appid -PathType Leaf ) )
{
    $msg = " Failed to locate '$steam_appid' from current location: '$(Get-Location)'"

    Write-Host "ERROR:" $msg -ForegroundColor Red

    Write-Log -Message $msg -level ERROR -logfile $pwrshelllog

    Start-Sleep -s 10
    Exit
}

Write-Log -Message "Found '$steam_appid' from current location '$(Get-Location)'" -level INFO -logfile $pwrshelllog


# For example, in CS:S, file locate ...steamapps\common\Counter-Strike Source\bin\vpk.exe

$vpkexe = ".\bin\vpk.exe"

if( -not ( Test-Path -Path $vpkexe -PathType Leaf ) )
{
    $msg = " Failed to locate '$vpkexe' from current location: '$(Get-Location)'"

    Write-Host "ERROR:" $msg -ForegroundColor Red

    Write-Log -Message $msg -level ERROR -logfile $pwrshelllog

    Start-Sleep -s 10
    Exit
}

Write-Host "`n Success: Found $vpkexe`n" -ForegroundColor Green

Write-Log -Message "Found '$vpkexe' from current location '$(Get-Location)'" -level INFO -logfile $pwrshelllog

Start-Sleep -s 1









# Check all *_dir.vpk files from 1st subfolder(s)

$dir_vpk = "*_dir.vpk"


$vpks = Get-ChildItem -Filter $dir_vpk -Depth 1


if ( $vpks -eq $null )
{
    $msg = " Failed to find any '$dir_vpk' files from current location: '$(Get-Location)'"

    Write-Host "ERROR:" $msg -ForegroundColor Red

    Write-Log -Message $msg -level ERROR -logfile $pwrshelllog

    Start-Sleep -s 10
    EXIT
}

$vpks = Resolve-Path -Relative $vpks.FullName

Write-Host " Success: Found VPK files:`n$($vpks|Out-String) `n" -ForegroundColor Green

Write-Log -Message "Found VPK files:`n$($vpks|Out-String)from current location '$(Get-Location)'" -level INFO -logfile $pwrshelllog

Start-Sleep -s 1





# Use vpk.exe with given vpk files


Write-Host " Executing program '$vpkexe', please hold...`n" -ForegroundColor Green

Write-Log -Message "Executing program '$vpkexe' from current location '$(Get-Location)'" -level INFO -logfile $pwrshelllog

$allfiles = @()

foreach ( $vpk in $vpks )
{

    # Parameter -dumpvpkfiles is enabled

    if ( $dumpvpkfiles -ne 0 )
    {
        $null = $vpk -match "(\w+).vpk"

        if ( $Matches[1] -gt 0 )
        {
            Write-Log -Message "-dumpvpkfiles $dumpvpkfiles, dump files into '.\$($Matches[1]).txt' from current location '$(Get-Location)'" -level DEBUG -logfile $pwrshelllog

            .$vpkexe l $vpk|Out-File ".\$($Matches[1]).txt"
        }
    }


   $allfiles += .$vpkexe l $vpk
}


if ( $allfiles.Count -le 0 )
{
    $msg = " Failed to collect output messages from program '$vpkexe' from current location: '$(Get-Location)'"

    Write-Host "ERROR:" $msg -ForegroundColor Red

    Write-Log -Message $msg -level ERROR -logfile $pwrshelllog

    Start-Sleep -s 10
    EXIT
}

Write-Host " Success: Found $($allfiles.Count) files `n" -ForegroundColor Green

Write-Log -Message "Found $($allfiles.Count) files" -level INFO -logfile $pwrshelllog

Start-Sleep -s 1


$results = @()


[regex] $a_regex = '^(\w+/.*/|\w+/).*$'

Write-Log -Message "Using regex pattern '$a_regex'..." -level INFO -logfile $pwrshelllog

for ( $a = 0; $a -lt $allfiles.count; $a++ )
{
    $null = $allfiles[$a] -match $a_regex


    if ( $Matches.count -gt 0 -and $results -notcontains $Matches[1] )
    {
        $results += $Matches[1]
    }

}


if ( $results.Count -le 0 )
{
    $msg = " Regex match failed or file paths not contain any folders aka directories"

    Write-Host "ERROR:" $msg -ForegroundColor Red

    Write-Log -Message $msg -level ERROR -logfile $pwrshelllog

    Start-Sleep -s 10
    EXIT
}

Write-Host " Success: Found $($results.Count) possible file paths `n" -ForegroundColor Green

Write-Log -Message "Found $($results.Count) possible file paths" -level INFO -logfile $pwrshelllog

Start-Sleep -s 1



Write-Log -Message "Begin creating empty folders into '.\hl2' folder" -level INFO -logfile $pwrshelllog

foreach ( $a in $results )
{
    $null = New-Item -Path "./hl2/$($a)" -ItemType Directory -Force
}

Write-Host " Empty folders have been created in '.\hl2' folder `n" -ForegroundColor Green

Write-Log -Message "`n-script ended`n-`n-" -level INFO -logfile $pwrshelllog

Start-Sleep -s 2

Write-Host " *** Powershell script finished! *** `n" -ForegroundColor Green
Start-Sleep -s 2


Write-Host "This script EXIT in 10 seconds, good bye!`n" -ForegroundColor Green
Start-Sleep -s 10




#end