Powershell scripting help needed - powershell

I am very new to powershell scripting. Trying to learn it from web. Now I am trying to do a script and facing some problem, so need some help ans suggestions from you people. I am giving description what I tried to do:
first of all I have declared 2 variables, then I used if statement to see if the variables are empty then it will show a warning message and it will ask for the inputs from the user and after that it will show the value of the variables. but it is giving some errors.
$workingdirectory = args[0]
$directoryname = args[1]
if ("$WorkingDirectory" -eq "")
{
Write-Warning "Parameter Required"
$WorkingDirectory = Read-Host "Enter the absolute path to working directory "
}
if ("$DirectoryName" -eq "")
{
Write-Warning "Paramater Required"
$DirectoryName = Read-Host "Enter a directory name to search for in $WorkingDirectory "
}
Write-Host "$WorkingDIrectory"
write-host "$DirectoryName"
When I run it, it is showing the following errors:
ARGS[0] : The term 'ARGS[0]' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
At C:\LAB_5-submission\mmbillah1_Lab_testdir.ps1:24 char:21
+ $WorkingDirectory = ARGS[0]
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (ARGS[0]:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
ARGS[1] : The term 'ARGS[1]' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the
name, or if a path was included, verify that the path is correct and try again.
At C:\LAB_5-submission\mmbillah1_Lab_testdir.ps1:25 char:18
+ $DirectoryName = ARGS[1]
+ ~~~~~~~
+ CategoryInfo : ObjectNotFound: (ARGS[1]:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I want to run like this: .\scriptname.ps1, if I use this then it will show the warning and ask for the two variables input.
and if I run this .\scriptname.ps1 C:\users\masum then it will ask for the second variable value only.

The root of your problem is simply syntax it should be $args[0] and $args[1] if you intend to use what you have now. What I would strongly suggest instead is to create parameters for your script, and then test if those parameters are valid, and if they aren't to prompt for them.
Parameters can be defined in a Param() block as such:
Param(
$workingdirectory,
$directoryname
)
That is very simple, but for your needs it works. You can add types to make sure the right kinds of things are passed as the parameter, and add tests to make sure the parameters are valid, but that goes beyond what we're doing here.
Then you would check to make sure that there is a value for each, and I would recommend making sure that the path is valid. Something like:
While([string]::IsNullOrEmpty($workingdirectory) -or !(Test-Path $workingdirectory)){
$workingdirectory = Read-Host "Enter a valid working directory"
}
That checks if the $workingdirectory variable is empty or just blank spaces, and if it actually has a value it will check to make sure it's a valid directory. If it is blank or the path isn't valid it prompts the user to enter a valid path. You would need to repeat that for the $directoryname variable.
So you would end up with something like:
Param(
$workingdirectory,
$directoryname
)
While([string]::IsNullOrEmpty($workingdirectory) -or !(Test-Path $workingdirectory)){
$workingdirectory = Read-Host "Enter a valid working directory"
}
While([string]::IsNullOrEmpty($directoryname) -or !(Test-Path $directoryname)){
$directoryname= Read-Host "Enter a valid target directory"
}
Write-Host $workingdirectory
Write-Host $directoryname

Related

String comparison not working in powershell

I am trying an if else condition in powershell using string comparison. I tried as per documentation using -eq operator. But getting below error. Here "Build.Reason" is a predefined variable. Not sure why its looking for cmdlet name for variable.
Write-Host "$(Build.Reason)"
if ($(Build.Reason) -eq "Manual" ) {
$temp = "https://url/api/qualitygates/project_status?&pullRequest=$(Build.Reason)"
Write-Host "Manual"
} else {
Write-Host "CI"
}
Error
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command ". 'D:\a\_temp\d7af16d6-ce3e-4dec-a636-9447962fdac4.ps1'"
Manual
Manual : The term 'Manual' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At D:\a\_temp\d7af16d6-ce3e-4dec-a636-9447962fdac4.ps1:7 char:5
+ if (Manual -eq "Manual" ) {
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (Manual:String) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CommandNotFoundException
It looks like $(Build.Reason) is a macro-style value provide by a CI system (it is not a PowerShell construct), which is expanded to become a literal part of the code before PowerShell sees it.
Therefore, if this value is to be treated as a string in the resulting PowerShell code, you need to quote it; e.g.:
if ("$(Build.Reason)" -eq "Manual") { # ...
Note that if there's a chance that $(Build.Reason) expands to a value with embedded " characters, they would have to be escaped as `". Similarly, if the value contains embedded $ chars., single-quoting should be used, which may then require escaping embedded single quotes as ''.
If this escaping cannot be performed at the source, you can use a verbatim here-string:
if (#'
$(Build.Reason)
'# -eq 'Manual') { # ...
Important: The closing '# must always be at the very beginning of the line.

Parsing a web page for text

I'm trying to search a webpage for a word "Green". It tells me things are fine but if it finds "Red" it tells me things are bad. What I've done below is very simple but I'm thinking its enough to ask the question.
$web = Invoke-WebRequest http://myip/vrsinfo/aghealth/DISTAGAR
$web.ToString() -split "[`r`n]" | Select-String "Green"
Here is what it returns
name="agSolarwindsHealth" value=Green readonly>
Here is what I've tried so far
if (name="agSolarwindsHealth" value=Green readonly>) {
'This number is 1'
} else {
'This number is not 1'
}
Error
name=agSolarwindsHealth : The term 'name=agSolarwindsHealth' is not recognized
as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct
and try again.
At line:3 char:5
+ if (name="agSolarwindsHealth" value=Green readonly>)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (name=agSolarwindsHealth:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Add folder to zip

I am facing a problem how to add folder to existing ZIP file.
This zip file is created by PowerShell also.
I can only use system classes provided by Powershell 5. I cannot use any of user packages or plugins (7zip included).
Here is my code:
function addFileToArchiveTest ($filePathToAdd, $archivePathToUpdate) {
if ([System.IO.File]::Exists($filePathToAdd) -or (Test-Path $filePathToAdd)) {
$file = [System.IO.Path]::GetFileName($filePathToAdd);
Write-Host $filePathToAdd.Name;
Write-Host $filePathToAdd;
Write-Host $archivePathToUpdate;
$archive = [System.IO.Compression.ZipFile]::Open($archivePathToUpdate, [System.IO.Compression.ZipArchiveMode]::Update);
$compressionLevel = [System.IO.Compression.CompressionLevel]::NoCompression;
[System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $filePathToAdd, $file, "$compressionLevel");
$archive.Dispose();
} else {
Write-Host "[ERROR#function] <AddFileToArchive>: <filePathToAdd> does not exist!";
Write-Host "[ERROR#function] <Variable<filePathToAdd>>: $filePathToAdd";
Write-Host "[ERROR#function] <Variable<archivePathToUpdate>>: $archivePathToUpdate";
}
}
I am thinking about variable $file - there might be a problem, because folder doesn't have an extension.
I run script like this:
PS> addFileToArchiveTest "C:\TestFolder\FolderToArchive" "C:\TestFolder\thereIsAlreadyZipFile.zip"
It returns with error:
Exception calling "CreateEntryFromFile" with "4" argument(s): "Access to the
path 'C:\TestFolder\FolderToArchive' is denied."
At C:\Users\user\Desktop\testfolder.ps1:196 char:13
+ [System.IO.Compression.ZipFileExtensions]::CreateEntryFro ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException
Noted I also try allow script and I am launching with admin rights.
Perhaps surprisingly, CreateEntryFromFile() is for adding files, not folders. You need to add each file individually:
Get-ChildItem $filePathToAdd | ForEach-Object {
[IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive, $_.FullName, $_.Name, "$compressionLevel")
}
As user #guiwhatsthat answered: PowerShell 5 does support Compress-Archive. It does exactly what you want.
That is working as I want.

PowerShell Native Cmdlet Set-Alias with Function and Switch

Question:
Is it possible to set an alias that calls both a function and a switch?
Here is an example I am working with.
Set-Alias -Name myidea -Value 'Test-FunctionIdea -SwitchIdea'
function Test-FunctionIdea {
param(
[switch]$SwitchIdea
)
if($SwitchIdea)
{
Write-Host 'Good Idea'
}
}
Here is the error I am having:
myidea : The term 'Test-FunctionIdea -SwitchIdea' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if
a path was included, verify that the path is correct and try again.
At line:1 char:1
+ myidea
+ ~~~~~~
+ CategoryInfo : ObjectNotFound: (Test-FunctionIdea -SwitchIdea:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
If it is possible please let me know how it's done. I've searched the internet for this and came up with no results.
You can check $MyInvocation.InvocationName and adjust the parameters inside the function:
function Some-Function([switch] $foo) {
if ($MyInvocation.InvocationName -eq 'foo') { $foo = $true }
}
Set-Alias foo Some-Function
The [usually negligible] advantage is that it doesn't create an additional execution context for the new function scope.

Userprofile messed up

I have a little problem here with my user profile path for the use with powershell.
I have set my profile.ps1 to this:
$Shell = Host.UI.RawUI
$Shell.WindowTitle="PowerShell obeys me!"
$Shell.BackgroundColor="White"
$Shell.ForegroundColor="Blue"
$size = $Shell.WindowSize
$size.width=120
$size.height=50
$Shell.WindowSize = $size
$size = $Shell.BufferSize
$size.width=120
$size.height=5000
$Shell.BufferSize = $size
but everytime i execute run poweshell, it shows some erors like this one:
Property 'WindowTitle' cannot be found on this object; make sure it exists and is settable.
At D:\data\d7bighs\Documents\WindowsPowerShell\profile.ps1:5 char:8
+ $Shell. <<<< WindowTitle="PowerShell obeys me!"
+ CategoryInfo : InvalidOperation: (WindowTitle:String) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
now is i check my profile it tells me this:
$profile
d:\data\myusername\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1
but if i check this through windows explorer it tells me this:
d:\User\myusername\Documents\WindowsPowerShell\profile.ps1
Im confused here because within explorer tells me d:\Useres but PS shows it as d:\data...
How can i change this or force PS to look after d:\users instead of d:\data?
a tiny error: $Shell = $Host.UI.RawUI, and you may need to create the profile first by
New-Item -Path $PROFILE -Type file
then edit it by
notepad $PROFILE