How to write output with new lines in Powershell - windows

I want to create a Powershell script that looks for a certain string in file contents.
Here is my script.ps1
$lookup = Read-Host -Prompt "Enter the word you're looking for:"
$res = sls "$lookup" (dir -Recurse *.txt, *.docx, *xlsx)
Write-output "$res"
Read-Host -Prompt "Press Enter to exit"
Looking for a string "A" from my test directory.
The output is below:
Enter the word youre looking for: A
C:\Users\koyamashinji\Downloads\test\test1.txt:1:ABCDEFGHIJKLMN C:\Users\koyamashinji\Downloads\test\test2.txt:1:ABCDEFGHIJKLMN C:\Users\koyamashinji\Downloads\test\test3.txt:1:ABCDEFGHIJKLMN C:\Users\koyamashinji\Downloads\test\test4.txt:1:ABCDEFGHIJKLMN
Press Enter to exit:
I would like to have a following output with new lines.
How do I get the output like this?
Enter the word youre looking for: A
C:\Users\koyamashinji\Downloads\test\test1.txt:1:ABCDEFGHIJKLMN
C:\Users\koyamashinji\Downloads\test\test2.txt:1:ABCDEFGHIJKLMN
C:\Users\koyamashinji\Downloads\test\test3.txt:1:ABCDEFGHIJKLMN
C:\Users\koyamashinji\Downloads\test\test4.txt:1:ABCDEFGHIJKLMN
Press Enter to exit:
Thanks for your help.

You need to remove the double quotes from the "$res" variable:
$lookup = Read-Host -Prompt "Enter the word you're looking for:"
$res = sls "$lookup" (dir -Recurse *.txt, *.docx, *xlsx)
Write-output $res <--------- HERE
Read-Host -Prompt "Press Enter to exit"

Related

Unable to use logical operator while comparing strings for input validation in Powershell

I am attempting to prompt a user for input and then validate if the users input matches one of two different options, and will exit if a correct input was not given.
In the example, I am asking the user to enter 'BOB' or 'TOM' as valid inputs, however when I run this code I will always get the message 'Server type not entered correctly', even when I enter BOB as an input for the prompt.
$ServerType = Read-Host -Prompt 'Enter Server Type (BOB or TOM)'
If ($ServerType -ne "BOB" -Or $ServerType -ne "TOM")
{
Write-Host -NoNewLine 'Server type not entered correctly'
}
I have also tried
If (($ServerType -ne "BOB") -or ($ServerType -ne "TOM"))
{
Write-Host -NoNewLine 'Server type not entered correctly'
}
However, when I only test for one value it works:
If ($ServerType -ne "BOB")
{
Write-Host -NoNewLine 'Server type not entered correctly'
}
Any ideas why I might be getting this?
As in my comment, the logical operator in this case should be -and but allow me to give you 2 examples where your validation could be improved.
First one is using the -match \ -notmatch comparison operators, which allows the use of regex:
$ServerType = Read-Host -Prompt 'Enter Server Type (BOB or TOM)'
if($ServerType -notmatch '^(bob|tom)$')
{
Write-Host -NoNewLine 'Server type not entered correctly'
}
Second one, is using a ValidateSet attribute:
try
{
[validateset('bob','tom')]
$ServerType = Read-Host -Prompt 'Enter Server Type (BOB or TOM)'
}
catch
{
Write-Host -NoNewLine 'Server type not entered correctly'
}

powershell script to delete x days old file automatically. pass two parameters in it one for path of file and other one for no. of days to keep files

I want to write a PowerShell script for deleting a folder automatically using notepad and I also want to add 2 parameters to this script. Whenever I run this script it asks for path and no. of days old file.
Param1 - location of the folder
Param2 - no. Of days to keep
$param1 = Read-Host -Prompt 'location of the folder'
$param2 = Read-Host -Prompt 'no. of days to keep'
Get-ChildItem $param1 -recurse |
Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays($param2)} |
Remove-Item
Is there any solution to pass parameters in the PowerShell script? In my code param1 is taking input but param2 is not taking any input.
First - please name your parameters properly - it's easier to read. :)
Second - if you want older than x - you have to .AddDays(-$days).
So it might look like this:
$path = Read-Host -Prompt 'location of the folder'
$days = Read-Host -Prompt 'no. of days to keep'
Get-ChildItem $path -Recurse |
#Mind the -$days (so we are looking for older than (today - X days)
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-$days) } |
Remove-Item #-WhatIf #for testing
The concept is the same as in Grzegorz's helpful answer, I just added some input validation and error handling.
$ErrorActionPreference = 'Stop'
$param1Block = {
try
{
[validatescript({Test-Path $_})]$z = Read-Host -Prompt 'location of the folder'
$z
}
catch
{
Write-Warning 'Invalid Path, try again.'
& $param1Block
}
}
$param2Block = {
try
{
[int](Read-Host -Prompt 'no. of days to keep')
}
catch
{
Write-Warning 'Only integers accepted, try again.'
& $param2Block
}
}
$param1 = & $param1Block
$param2 = & $param2Block
if([math]::Sign($param2) -ne -1)
{
$param2 = -$param2
}
Get-ChildItem $param1 -Recurse |
Where-Object -Property LastWriteTime -LT ([datetime]::Now).AddDays($param2) |
Remove-Item

Replacing words in powershell using a variable

i want to write a script that takes inputfrom the user and changes a word in a file to what the user entered.
saw some people doing it like this:
(Get-Content c:\temp\test.txt).replace('word1', 'word2') | Set-Content c:\temp\test.txt
the problem is that i want to replace a word with a variable, so when i put it between the commas it wont work.
i want it to be something like that:
$word = read-host " please enter a word"
(Get-Content c:\temp\test.txt).replace('oldtext', '$word') | Set-Content c:\temp\test.txt
is there any way to do that?
UPDATE:
tried it like this:
$path = "C:\Users\tc98868\Desktop\dsp.json"
$word = read-host "please enter a word"
(Get-Content $path).replace('dsp.tar.gz', $word) | Set-Content $path
and it still doesnt work.
Remove the single quote from the $word
PowerShell not expanding variables inside a single quote, it threat is as a string
$word = read-host " please enter a word"
(Get-Content c:\temp\test.txt).replace('oldtext', $word) | Set-Content c:\temp\test.txt
For PS Version 2:
(Get-Content c:\temp\test.txt) -replace 'oldtext', $word | Set-Content c:\temp\test.txt

New-ADUser Error

I am prepping a script for our accounts management team that'll create users accounts fairly quickly. I seem to always get an error stating:
New-ADUser : A value for the attribute was not in the acceptable range of values
I have looked online and through here a bit but some of the solutions that others posted didn't work for me. The code is below:
Write-Host "New Business Services Account" -ForegroundColor Green
$Name = Read-Host "Enter First and Last Name"
$DisplayName = $Name
$GivenName = Read-Host "Enter First Name"
$Surname = Read-Host "Enter Last Name"
$EmailAddress = Read-Host "Enter Email Address"
$SamAccountName = Read-Host "Enter SamAccountName"
#$UserPrincipalName = $GivenName.$Surname + "#{entrustenergy}.com"
$Office = Read-Host "Enter Office"
$City = "Houston"
$State = "TX"
$ZipCode = Read-Host "Enter Zip Code"
$Country = "United States"
$Company = "Entrust Energy, Inc."
$JobTitle = Read-Host "Enter Job Title"
$Department = Read-Host "Enter Department"
$Manager = Read-Host "Enter Managers Username"
$Path = "PathOUisHere"
$Password = Read-Host "Enter Password"
New-ADUser -Name "$Name" -GivenName "$GivenName" -Surname "$Surname" `
-DisplayName "$DisplayName" -EmailAddress "$EmailAddress" `
-SamAccountName "$SamAccountName" -StreetAddress "$Address" -City "$City" `
-State "$State" -PostalCode "$ZipCode" -Country "$Country" `
-Company "$Company" -Title "$JobTitle" -Department "$Department `
-Manager "$Manager" -Path "$Path" -Enabled $true `
-AccountPassword (ConvertTo-SecureString "$Password" -AsPlainText -Force) `
-ChangePasswordAtLogon $true -PassThru
You're passing '-StreetAddress "$Address"' but it's never supplied in the read-host section.
Going out on a limb I'd guess that the error is caused by the value you provide for the property -Country. From the documentation:
Country
Specifies the country or region code for the user's language of choice. This parameter sets the Country property of a user object. The LDAP Display Name (ldapDisplayName) of this property is "c". This value is not used by Windows 2000.
The following example shows how set this parameter.
-Country "IN"
Change $Country = "United States" to $Country = "US" and the error should disappear.
See also this answer to a related question.

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