Powershell does not put system variable in path - powershell

Putting the following in a Powershell console, it outputs the variable value:
[Environment]::UserName
Putting this:
PS C:\> Test-Path C:\Users\${[Environment]::UserName}\AppData\Local\Microsoft\Outlook
False
Odd, so I went ahead and outputted to the console itself:
PS C:\> Write-Host C:\Users\${[Environment]::UserName}\AppData\Local\Microsoft\Outlook
C:\Users\\AppData\Local\Microsoft\Outlook
It returns blank. Why? Putting the variable directly to console does output its value while passing it like that it doesnt...

You should use $env:LOCALAPPDATA since you don't have to hard code c:\. You should also use the Join-Path cmdlet if you want to join a path:
$path = Join-Path $env:LOCALAPPDATA 'Microsoft\Outlook'

Are you sure the path being output is correct; i.e. that the username's appended? When I run it I see c:\Users\\AppData\...; i.e. no username.
Working code:
$fn = ("C:\Users\{0}\AppData\Local\Microsoft\Outlook" -f $env:Username)
Write-Host $fn
Test-Path $fn

Related

How can I pass a result of a program as an argument to cmdlet?

Let say there are two separate commands that work well:
$x = where.exe cmd.exe
Get-Item -Path $x
How can I write the above in one line only, without using variable x ?
I tried the below, but it didn't work
Get-Item -Path {where.exe cmd.exe}
Get-Item -Path $(where.exe cmd.exe)

How can I suppress/hide WMI output when using Setting an object? [duplicate]

I have a PS script:
script.ps1
[System.Xml.XmlDocument] $Config;
function Get-ScriptDirectory
{
Split-Path $script:MyInvocation.MyCommand.Path
}
function Load-Config
{
$configPath = Join-Path (Get-ScriptDirectory) config.xml
$global:Config = [xml](gc $configPath)
}
Load-Config
config.xml
<Configuration>
</Configuration>
Later in the script I'm working with $Config variable. When I run this script it writes the output to the console, which contains the root element of the xml. Something like:
Configuration
--------------
Is there exists any way how to suppress this output?
Thanks.
If you don't want the output of a command to be printed out to the console, you can discard it by piping it or redirecting it to Out-Null. For example both will work:
$Config | Out-Null
$Config > Out-Null
If you're familiar with Unix-like operating systems, Out-Null is conceptually equivalent to /dev/null.
Probably the output isn't caused by the assignment statement (a voidable statement), but by this line:
[System.Xml.XmlDocument] $Config;
In PowerShell, typically, all statements return a value (except for voidable statements). I think that the first time you run the script no output will be written to the console. However on subsequent runs $Config will still contain the value of the previous run, and its value will be written to the screen.
piping to the Out-Null cmdlet:
[System.Xml.XmlDocument] $Config | Out-Null
casting to void:
[void][System.Xml.XmlDocument]$Config
assigning to $null:
$null = $Config
or simply not 'declaring' the $Config variable
are ways to suppress this behaviour.
Somewhere you're dumping the variable from your script. As it falls out of the pipe it gets passed to Out-Host and that will yield the output you see.
The actual solution is to make sure you don't return anything from your script. As I cannot see your code I can't point to where, but somewhere there is a pipeline or statement that leaks the object into output. Are you sure you're using an assignment at every place you need?
A few Options:
# Pipe to the Out-Null cmdlet
$Config | Out-Null
# Cast to void
[void]$Config
# assign to $null
$null = $Config
# redirect to $null
$Config > $null

Trim quotes from read-host directory stored as variable

I have a small Powershell script I wrote to help rename folders of files, based off the filenames in another folder.
I have two read-host lines that catch the input from the user and store the input as the source folder and destination folder as strings. This makes life easier as I can drag and drop rather than full typing the path.
The problem is that Powershell keeps throwing errors, saying it can't find the drive "X:
This seems to be being caused by the quotes around the path, as removing them after dragging and dropping works fine.
Here is how it is captured:
$source = Read-Host "Source folder"
$destination = Read-Host "Destination folder"
[array]$a = Get-ChildItem $source
[array]$b = Get-ChildItem $destination
What is the easiest way to remove the quotes from those strings, before running the Get-ChildItem command? I have tried things like $source.replace, $_. trim and also $source -replace ('"', "")
Can't seem to get this to work.
Use single quotes, like so:
PS C:\> $foo = 'x:\"some weird\path"'
PS C:\> $foo
x:\"some weird\path"
PS C:\> $foo.Replace('"', '')
x:\some weird\path
PS C:\> $foo -replace '"', ''
x:\some weird\path

How to suppress PowerShell Get-Content output

I have a PS script:
script.ps1
[System.Xml.XmlDocument] $Config;
function Get-ScriptDirectory
{
Split-Path $script:MyInvocation.MyCommand.Path
}
function Load-Config
{
$configPath = Join-Path (Get-ScriptDirectory) config.xml
$global:Config = [xml](gc $configPath)
}
Load-Config
config.xml
<Configuration>
</Configuration>
Later in the script I'm working with $Config variable. When I run this script it writes the output to the console, which contains the root element of the xml. Something like:
Configuration
--------------
Is there exists any way how to suppress this output?
Thanks.
If you don't want the output of a command to be printed out to the console, you can discard it by piping it or redirecting it to Out-Null. For example both will work:
$Config | Out-Null
$Config > Out-Null
If you're familiar with Unix-like operating systems, Out-Null is conceptually equivalent to /dev/null.
Probably the output isn't caused by the assignment statement (a voidable statement), but by this line:
[System.Xml.XmlDocument] $Config;
In PowerShell, typically, all statements return a value (except for voidable statements). I think that the first time you run the script no output will be written to the console. However on subsequent runs $Config will still contain the value of the previous run, and its value will be written to the screen.
piping to the Out-Null cmdlet:
[System.Xml.XmlDocument] $Config | Out-Null
casting to void:
[void][System.Xml.XmlDocument]$Config
assigning to $null:
$null = $Config
or simply not 'declaring' the $Config variable
are ways to suppress this behaviour.
Somewhere you're dumping the variable from your script. As it falls out of the pipe it gets passed to Out-Host and that will yield the output you see.
The actual solution is to make sure you don't return anything from your script. As I cannot see your code I can't point to where, but somewhere there is a pipeline or statement that leaks the object into output. Are you sure you're using an assignment at every place you need?
A few Options:
# Pipe to the Out-Null cmdlet
$Config | Out-Null
# Cast to void
[void]$Config
# assign to $null
$null = $Config
# redirect to $null
$Config > $null

'Get-ChildItem -Include/-Exclude' in PowerShell doesn't filter if passed as an argument to a function

I have a problem getting a filter argument to Get-ChildItem in a function.
The following works fine and displays a whole list of files:
c:\temp\Get-ChildItem -Include *deleteme*.txt -Recurse
Now say I have the following script
#file starts here
#filename = GetLastFile.ps1
param([string] $filter)
$files = Get-ChildItem $filter
Write-Host $files #should print all matching files but prints nothing
$file = $files | Select-Object -Last 1;
$file.name #returns filename
#File ends here
Now trying to run the script,
c:\temp.\GetLastFile.ps1 "-Include *deleteme*.txt -Recurse"
returns nothing.
Supplying a filter, *.*, works fine. It seems to be failing due to the -Include or -Exclude. Any ideas?
You're starting to get into an area where where Powershell 2.0 proxy functions can help. However, short of that, here's a simple way in PowerShell 2.0 to do this assuming all you need is -Include and -Recurse. Actually, I would recommend using -Filter instead it will do what you want and frankly it's quite a bit faster (4x on some of my tests) because -filter uses filesystem filtering provided by the OS whereas -include is processed by PowerShell.
param([string]$Filter, [switch]$Recurse)
$files = Get-ChildItem #PSBoundParameters
Write-Host $files #should print all matching files but prints nothing
$file = $files | Select-Object -Last 1;
$file.name #returns filename
The # symbol is used to "splat" an array or hashtable across the parameters to a command. The $PSBoundParameters variable is an automatic variable new to PowerShell 2.0 that is defined in functions. It's a hashtable that contains all the bounded (named and positional) parameters e.g.:
PS> function foo($Name,$LName,[switch]$Recurse) { $PSBoundParameters }
PS> foo -Name Keith Hill -Recurse
Key Value
--- -----
Name Keith
Recurse True
LName Hill
When you splat a hashtable like this against a command, PowerShell will map the key's (e.g. Recurse) value to the parameter named Recurse on the command.
I believe what is happening is your $filter parameter is being treated as a single string argument to the Get-ChildItem command. As such, unless you have a directory named "-Include deleteme.txt -Recurse", the command will always return nothing.
As for fixing your problem, well, there are a bunch of ways you could approach it. Probably one of the more versatile ways is to switch program behavior if the the $filter argument is passed, and instead of passing the entire filter string just pass the "deleteme.txt" string.
You can use Invoke-Expression to execute a command stored in a variable. For example:
param([string] $filter)
$files = Invoke-Expression "Get-ChildItem $filter"
Write-Host $files
$file = $files | Select-Object -Last 1
$file.name