1

I recently added a touch function in PowerShell profile file

PS> notepad $profile
function touch {Set-Content -Path ($args[0]) -Value ($null)}

Saved it and ran a test for

touch myfile.txt

error returned:

touch : The term 'touch' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:1
+ touch myfile
+ ~~~~~
    + CategoryInfo          : ObjectNotFound: (touch:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
Ansgar Wiechers
  • 175,025
  • 22
  • 204
  • 278
  • 2
    Did you close and reopen the powershell console? –  Aug 14 '18 at 12:21
  • Yes I did it multiple times, still did not work. – Muhammad Yasir Javed Aug 14 '18 at 12:23
  • 3
    That is *not* a proper implementation of `touch`, unless you like the idea of accidentally destroying files. If this "function" of `touch` is all you need, consider renaming it `Empty-File` or similar... Or consider a more careful implementation, like `Add-Content $File $null ; (dir $File).LastWriteTime = Get-Date`. – Jeroen Mostert Aug 14 '18 at 12:32
  • 1
    Have you double checked the path of the profile file and that it actually gets loaded? Type `explorer $profile` in the console to verify the path and maybe add `write-host loaded` to the profile to verify it gets loaded. – marsze Aug 14 '18 at 12:50

3 Answers3

4

With PowerShell there are naming conventions for functions. It is higly recommended to stick with that if only to stop getting warnings about it if you put those functions in a module and import that.

A good read about naming converntion can be found here.

Having said that, Powershell DOES offer you the feature of Aliasing and that is what you can see here in the function below.

As Jeroen Mostert and the others have already explained, a Touch function is NOT about destroying the content, but only to set the LastWriteTine property to the current date. This function alows you to specify a date yourself in parameter NewDate, but if you leave it out it will default to the current date and time.

function Set-FileDate {
    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipeline = $true, Mandatory = $true, Position = 0)]
        [string[]]$Path,
        [Parameter(Mandatory = $false, Position = 1)]
        [datetime]$NewDate = (Get-Date),
        [switch]$Force
    )
    Get-Item $Path -Force:$Force | ForEach-Object { $_.LastWriteTime = $NewDate }
}
Set-Alias Touch Set-FileDate -Description "Updates the LastWriteTime for the file(s)"

Now, the function has a name PowerShell won't object to, but by using the Set-Alias you can reference it in your code by calling it touch

Theo
  • 35,300
  • 7
  • 15
  • 27
  • 1
    Just to mention it, a common use of touch is to create a file of zero length if it doen't already exist. Otherwise +1 –  Aug 14 '18 at 14:29
3

Here is a version that creates a new file if it does not exist or updates the timestamp if it does exist.

Function Touch-File
{
    $file = $args[0]
    if($file -eq $null) {
        throw "No filename supplied"
    }

    if(Test-Path $file)
    {
        (Get-ChildItem $file).LastWriteTime = Get-Date
    }
    else
    {
        echo $null > $file
    }
}

If you have a set of your own custom functions stored in a .ps1 file, you must first import them before you can use them, e.g.

Import-module .\MyFunctions.ps1 -Force
BigJoe
  • 131
  • 2
  • 1
    Bad idea. If the file is created after `Test-Path` tests (which could happen in another session), it will still be merrily destroyed. Aside from that, `echo $null > $file` will not create an empty (0 byte) file; it will be a 2 byte file containing a BOM. Instead of testing, `Add-Content $file $null` will create the file if it does not exist, or leave it alone if it does. – Jeroen Mostert Aug 15 '18 at 13:20
  • @JeroenMostert Add-Content is better. Why not make an answer? – Steven T. Cramer Sep 28 '19 at 08:26
0

To avoid confusion:

  • If you have placed your function definition in your $PROFILE file, it will be available in future PowerShell sessions - unless you run . $PROFILE in the current session to reload the updated profile.

    • Also note that loading of $PROFILE (all profiles) can be suppressed by starting a session with powershell.exe -NoProfile (Windows PowerShell) / pwsh -NoProfile (PowerShell (Core)).
  • As Jeroen Mostert points out in a comment on the question, naming your function touch is problematic, because your function unconditionally truncates an existing target file (discards its content), whereas the standard touch utility on Unix-like platforms leaves the content of existing files alone and only updates their last-write (and last-access) timestamps.

  • See this answer for more information about the touch utility and how to implement equivalent behavior in PowerShell.

mklement0
  • 245,023
  • 45
  • 419
  • 492