The challenge is that nowadays filename extensions are a convention, and that most APIs, including .NET's, consider anything after the last .
, if any, to be the extension, even if it isn't meant to be one. E.g., in A.B.C. Mini
, . Mini
(sic) is considered the extension, whereas
-Filter *.
in effect only matches names that contain no .
at all.
If you're willing to assume that any file that doesn't end in .
followed by 3 characters (e.g., .pdf
) is an extension-less file, you can use the following:
# Note: Works with 3-character extensions only, doesn't limit what those chars.
# may be.
Get-ChildItem -File C:\TEST |
Where-Object Extension -NotLike '.???' |
Rename-Item -NewName { '{0}.xml' -f $_.FullName } -WhatIf
Note: The -WhatIf
common parameter in the command above previews the operation. Remove -WhatIf
once you're sure the operation will do what you want.
If you need to match what characters are considered part of an extension more specifically and want to consider a range of character counts after the .
- say 1 through 4 - so that, say, .1
and .html
would be considered extensions too:
# Works with 1-4 character extensions that are letters, digits, or "_"
Get-ChildItem -File C:\TEST |
Where-Object Extension -NotMatch '^\.\w{1,4}$' |
Rename-Item -NewName { '{0}.xml' -f $_.FullName } -WhatIf
Note the use of a regex with the -notmatch
operator.
Regex ^\.\w{1,4}$
in essence means: match any extension that has between 1
and 4
word characters (\w
), where a word characters is defined as either a letter, a digit, or an underscore (_
).
See this regex101.com page for a detailed explanation and the ability to experiment.