PowerShell solutions:
PowerShell 7+ solution:
[Linq.Enumerable]::Zip(
[string[]] (Get-ChildItem . -File).FullName,
[string[]] (Get-Content FileNames.txt)
) | Rename-Item -LiteralPath { $_.Item1 } -NewName { $_.Item2 } -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.
The above uses . to target files in the current directory; adapt as needed.
The System.Linq.Enumerable.Zip method allows convenient enumeration of pairs of collection elements, as 2-element tuples; note that the arguments must be explicitly typed with casts ([string[]]) in order for PowerShell to resolve the method call correctly; generally, note that PowerShell, as of 7.0, lacks support for .NET extension methods (which requires explicit use of [System.Linq.Enumerable] here) and comprehensive support for calling generic methods, though there are feature requests on GitHub - see here and here.
These tuples are piped to Rename-Item, whose parameters are bound via delay-bind script blocks to dynamically access each input tuple's properties.
PowerShell 6- solution:
# Read the array of lines == new file names from FileNames.txt
$names = Get-Content FileNames.txt
# Get as many files as new file names; '.' targets the current directory;
# Adapt as needed.
$files = (Get-ChildItem . -File)[0..($names.Count-1)]
# Perform the renaming.
$i = 0
$files | Rename-Item -NewName { $names[$script:i++] } -WhatIf
Note: The $i variable is referred to as $script:i in the delay-bind script block ({ ... }), because the script block runs in a child scope.
To make this also work in cases where the parent scope isn't also the script scope, use (Get-Variable -Scope 1 i).Value++ instead of $script:i++.