How to set a variable in a powershell command - windows

I am trying to declare and set a variable in a powershell command. Is that possible?
I was hoping to do something like this:
"$name" = "I219" | Get-NetAdapter | where Name -Match "$name"
Is this possible or can this only be done in a .ps script?

It can be done easily by just hitting enter in the console after declaring your variable:
$name = "I219" # now hit enter
To access the variable, type it in the console and hit enter again:
$name # hit enter => returns I219
Now use it with your command:
Get-NetAdapter | where { $_.Name -Match $name }
Or as a one-liner:
$name = "I219"; Get-NetAdapter | where { $_.Name -Match $name }

Related

How to display PowerShell results horizontally instead of vertically?

For example, you specified a variable as shown below.
$data1 = get-psdrive | where-object {$_.name -like 'c'} | select -expandproperty used
$data2 = get-psdrive | where-object {$_.name -like 'c'} | select -expandproperty free
echo $data1,data2
The output is vertical.
$data1
$data2
I used write-host -nonewline to display output horizontally, but the command does not export to txt
write-host $data1 -nonewline; write-host $data2 -nonewline >> c:\test.txt
How can I display horizontally and export in txt?
How about converting to json (or csv)? Note that ">>" can mix encodings, but add-content doesn't.
get-psdrive c | select used, free | ConvertTo-Json -Compress |
add-content test.txt
get-content test.txt
{"Used":217365741568,"Free":21004943360}
Or just join them. Too bad select -expand doesn't work with multiple properties.
psdrive c | % { ($_.used,$_.free) -join ',' }
217382371328,20988313600
You can't use Write-Host for this. Even if you change to Write-Host -NoNewLine it'll still never work because Write-Host is intended for directly writing into the screen and can't be redirected unless you use PowerShell 5+ and redirect the stream number 6 (Information stream)
Write-Host -NoNewLine $data1,$data2 6>output.txt
in which case it doesn't print out to string of course. In short Write-Host in PowerShell 5+ doesn't write to stdout but the Information stream
The real solution to writing to screen with the ability to redirect to file or pipe to another command is to use Write-Output (which echo is an alias to), and simply use a single string to write to a single line
Write-Output "$data1,$data2"
echo "$data1,$data2"
echo ($data1 + "," + $data2)
See Write-Host Considered Harmful for more details
Use a double quote string with your variables: Write-Host “$data1,$data2”
Read more https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7.1

Running PowerShell Command Directly On CMD Gives Index Was Out Of Range Error

The command below is designed to list expired user accounts:
powershell -c "Get-LocalUser | Where-Object { $_.AccountExpires -le (Get-Date) -and $null -ne $_.AccountExpires } | Select-Object Name, AccountExpires"
Running directly on PowerShell seems to run fine, however, when I run the same command via CMD, it gives the error below:
Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index').
I believe the issue is related to the $null parameter but I need this to exclude blank matches from the output. Does anyone know a way of fixing this error? Or an alternative method to no match blank output?
You should make things clear when using operators:
powershell -c "Get-LocalUser | Where-Object { ($_.AccountExpires -le (Get-Date)) -and ($null -ne $_.AccountExpires) } | Select-Object Name, AccountExpires"
This works fine for me
It might not be $null, try an empty string instead:
("" -ne $_.AccountExpires)

powershell select-string output for loop foreach

I'm traditional bash user therefore i don't understand how to work foreach in powershell.
Powershell
I need output
Vasya
http://192.168.10.61:8085/data.json
Misha
http://192.168.10.82:8085/data.json
but I receive another output
Vasya
Misha
http://192.168.10.61:8085/data.json
http://192.168.10.82:8085/data.json
Script
$pspath="E:\monitor.ps1"
$txtpath="E:\temp.txt"
$user1="Vasya"
$user2="Misha"
$ip1="http://192.168.10.61:8085/data.json"
$ip2="http://192.168.10.82:8085/data.json"
$list = #"
${user1}-${ip1}
${user2}-${ip2}
"#
foreach ($zab in $list)
{
$regex_url = 'http://\d+.\d+.\d+.\d+:\d+/data.json'
$regex_name = "([A-Z]|[a-z])\w+"
$name = echo $zab |%{$_.split('-')} |sls -pattern $regex_name -AllMatches |%{$_.Matches -notmatch 'http|json|data'} |%{$_.Value}
$url = echo $zab |%{$_.split('-')} |sls -pattern $regex_url -AllMatches |%{$_.Matches} |%{$_.Value}
echo $name
echo $url
}
Bash
In bash work's perfect.
Script
#!/bin/bash
users="Vasya-http://192.168.10.61:8085/data.json Misha-http://192.168.10.82:8085/data.json"
for zab in $users; do
name=$(echo $zab |cut -f 1 -d -)
url=$(echo $zab |cut -f 2 -d -)
echo $name
echo $url
done
exit 0
Help guys my hands are tied.
This:
$list = #"
${user1}-${ip1}
${user2}-${ip2}
"#
is a single multi-line string, so the foreach loop is redundant.
Split the string before running Select-String:
foreach($zab in $list -split '\r?\n'){
...
}
Your PowerShell script is quite different from the bash script.
I don't know if you need the greater complexity with the Select-String for other reasons,
but in PowerShell it could also be as easy as:
$users="Vasya-http://192.168.10.61:8085/data.json Misha-http://192.168.10.82:8085/data.json"
foreach($zab in ($users -split ' ')){
$name,$url = $zab -split '-',2
[PSCustomObject]#{
Name = $name
Url = $url
}
}
for this sample object oriented output:
Name Url
---- ---
Vasya http://192.168.10.61:8085/data.json
Misha http://192.168.10.82:8085/data.json

Converting Process List to HTML Shows Only Single Process

I have an PowerShell script which contains two variables:
$d: Array: Get TCP Connection, Just (ID) of each Process.
$gns: get name of each process in variable $d.
$d = #(Get-NetTCPConnection | Select -Expand OwningProcess)
foreach ($s in $d) {
$gns = Get-Process | Where-Object {$_.Id -eq $s} | Select -Expand Name
}
ConvertTo-HTML -PostContent $gns | Out-File c:\temp\TableHTML.html
Invoke-Item c:\temp\TableHTML.html
Result:
As you can see, the result shows just one process name, which is wrong!
I want to show all process names in the result.

Retrieve parameters from file - Windows PowerShell

I am writing a super-easy script in PowerShell. The target of this script is to read a list of server names from a txt file and a command block from another txt file. The result of the operation shold be a third txt file containing the information.
Here some code:
cls
$usr = Read-Host "Please insert username, you'll be asked for password later"
$path = Read-Host "Insert a valid path for ServerList.txt file"
$serverList = Get-Content -Path $path | Out-String
$path = Read-Host "Insert a valid path fom Command.txt file"
$commandBlock = Get-Content -Path $path | Out-String
echo "Command: " $commandBlock "will be executed on " $serverList
echo "Press CTRL+Z to abort or"
pause
Invoke-Command -ComputerName $serverList -ScriptBlock { $commandBlock } -credential $usr
Serverlist.txt is a plain text containing something like "server1,server2,server3" and command.txt contain only this "Get-WmiObject Win32_BIOS | Select-Object SerialNumber"
Why the error is Invoke-Command : One or more computer names are not valid. If you are trying to pass a URI, use the -ConnectionUri parameter, or pass URI objects
instead of strings. ?
I even tried to substitute $serverlist with $serverlist.toString() but it's not working. I read somewhere that in this case $serverlist is an Array, how do I do to make everything work?
Consider that https://technet.microsoft.com/en-us/library/hh849719.aspx Invoke-Commands work with "server1,server2,server3" format if you put the string via console.
Your $serverList isn't a list, it's a single string of server1,server2 etc. To make it into an array, you can use -split to split the string by commas.
$serverList = Get-Content -Path $path | Out-String
$serverList = $serverList -split ","
For further understanding of why this doesn't work as you expect, please see the parsing and command syntax help files:
Get-Help about_Parsing
Get-Help about_Command_Syntax
$serverlist
When your text file contains the line server1,server2,server3, this command:
Get-Content -Path .\file.txt | Out-String
Just results in the string server1,server2,server3 and a newline - that's not a valid hostname.
Either format your text file like this (Get-Content automatically splits on line breaks):
server1
server2
server3
or split the string(s) from the file yourself:
$Serverlist = Get-Content -Path $Path | ForEach-Object { $_ -split "," }
$commandblock
For the command block part to work, you can't just drop a string into a ScriptBlock and expect it to execute - you need to recreate it as executable code:
$Code = Get-Content -Path $path -Raw
$CommandBlock = [scriptblock]::Create($Code)
# Now you can do this
Invoke-Command -ScriptBlock $CommandBlock

Resources