IF Statement not working in Powershell - powershell

I've been trying to get an IF-ELSE clause to work within my little powershell v2 script, and I think I'm having some problems with my parsing. Here's the code I have currently:
$dir = test-path C:\Perflogs\TestFolder
IF($dir -eq "False")
{
New-Item C:\Perflogs\TestFolder -type directory
get-counter -counter $p -Continuous | Export-Counter C:\PerfLogs\TestFolder\Client_log.csv -Force -FileFormat CSV -Circular -MaxSize $1GBInBytes
}
Else
{
get-counter -counter $p -Continuous | Export-Counter C:\PerfLogs\TestFolder\Client_log.csv -Force -FileFormat CSV -Circular -MaxSize $1GBInBytes
}
So basically I want it to establish the $dir variable as testing to see if the path I want exists. If it doesn't, it should create that folder and run the counters. If it does, it should not create the folder but should still run counters.
I've got $p defined elsewhere, and the get-counters statement works fine. Right now, whether the folder exists or not I'm getting an error about new-item not working.
Am I using the wrong operator for -eq after doing that test?

You should have:
if ($dir -eq $false)
because the string "False" is not equal to the boolean value $false.

Try changing this:
IF($dir -eq "False")
to this:
IF($dir -eq $false)

x0n already answered, so I wont repeat that, but I noticed another "Gotcha" you should be aware of.
Your code is trying to test for the existence of a directory "TestFolder", however you test-path command is not restricted to checking only for directories. Meaning, if you actually happen to have a file by the same name "TestFolder" it will still return true.
To be more careful, you should add the "-PathType Container" switch so that it will fail if there is a file by that name and only pass if there is a directory by that name.
$dir = test-path C:\Perflogs\TestFolder -PathType Container

In addition to the other answers about $false, I've had syntax issues with v3. Specifically
if($dir -eq $false)
{
didn't work.
if($dir -eq $false){
did work. YMMV, but you've been warned.

It might work
If($? -ne 0)
if the given condition is false, which is defined in earlier variables(This is not for the above question)
If($dir -contains 'False')

Related

How do I get the path of a directory where a file SQL backup is missing?

The task is to track the execution of SQL backups. One of the tracking mechanisms is to browse the directory where the backups are saved and if the file is missing, you can send an email with the full address of the directory where the file is missing. This is what I am trying to implement with Powershell script, but for some reason my script doesn't work and doesn't give me the information I need.
$list = Get-ChildItem -Path network_path_to_share -Recurse -File | Where-Object {$_.DirectoryName -like '*FULL*' -and $_.LastWriteTime -ge (Get-Date).AddDays(-6)}
$fileExists = Test-Path $list
If ($fileExists)
{
#Do Nothing
}
Else
{
$list | Select DirectoryName
}
Can anyone help?
I suppose what you need is to test each file or path individually. You take Get-ChildItem with recurse, so it returns multiple files and stores them in $list.
If you do something like
Foreach ($item in $list) {
$fileexists = Test-Path $item
If ($fileexists -eq $false) {
do something }
}
You should be good to go. This would cycle through all items and does whatever you need to be done. If you compare against $false, you wouldn't need the else statement, and you could also just put "Test-Path" into the if-statement like
If (Test-Path $item -eq $false) {}
Edit: Sorry I accidentally posted the answer before finishing it lol
Also, as stackprotector correctly points out, Get-ChildItem can only retrieve items that exist, because how should it detect missing files.
If you're wanting to check for something that is missing or doesn't exist, you need to start with a known condition, e.g.: either the server names or expected file or directory names.
If you know that, then you can create a static list (or dynamically query a list from Active Directory for your SQL servers or something (assuming the backup file names correspond to the server names)) and then check the files that were created and output the missing ones for triage.
Here is a modification to your script (essentially the opposite of what you did) that might point you in the right direction:
## List of expected files
$ExpectedFiles = #(
'File1.bak',
'File2.bak',
'File3.bak',
'File4.bak'
'...'
)
## Get a list of created files
$list = Get-ChildItem -Path network_path_to_share -Recurse -File | Where-Object {$_.DirectoryName -like '*FULL*' -and $_.LastWriteTime -ge (Get-Date).AddDays(-6)} | Select -ExpandProperty Name
## Check whether each expected file exists in the array of backups that actually were created
foreach ($file in $ExpectedFiles) {
if (-not(Test-Path $list)) {
"$($file) is missing!"
}
}

Powershell - Declaring paths with "$_.pdf" in it

As title says.
I have several if-statements with "Test-Path" in it so it'd be much better if I just declare the variables right away.
$jobs = Get-ChildItem d:\Path\* -recurse -include *.pdf,*.idx |
Select-Object -expand basename |
Sort-Object
$jobs | foreach-object{
if ((test-path d:\Path\$_.idx) -and (test-path d:\path\$_.pdf)){
move-item d:\Path\$_.idx d:\Path
move-item d:\path\$_.pdf d:\Path
}
else {
....
}
}
The file name is varying all the time. That's why I'm using "$_.pdf" for example. This is just a simple example. Add even one more file extension to this and yeah. The code functions like "If pdf and idx basenames are true/equal, move them"
This works completely fine, it's just that putting in the paths for each if statement makes it more confusing.
Any help would be appreciated. Thanks in advance!
Test-Path can take an array of items to be tested. When used so, it will return an array of boolean values. Should that array contain at least one $false, there is at least one missing file. If there isn't, all the files are present.
An example is like so,
# Create a few test files
set-content foo.idx ''
set-content foo.dpf ''
set-content foo.pub ''
# Instead of foo, you'd populate $s with file's basename
# and use a foreach loop
$s ="foo"
# Test if the trio exists. Note variable $s that contains the basename
if( (Test-Path #(".\$s.idx", ".\$s.dpf", ".\$s.pub")) -contains $false){
"nay" # Go here if there was at least one false
}else{
"aye" # go here if all were true
}
# Output
aye
# Change one extension, so trio doesn't exist
if( (Test-Path #(".\$s.idx", ".\$s.dpf", ".\$s.bub")) -contains $false) {
"nay" # Go here if there was at least one false
}else{
"aye" # go here if all were true
}
# Output
nay
I'm dumb.
I just have to put $path\$_.pdf there. thats it

Powershell Return only folders that exist

We are deleting a load of XP profiles to save disk space. Some profile folders for XP exist as well as those for the same user with the .V2 for windows 7. Id like to use powershell to return only those XP profiles that exist.
Here is my code so far
$path = "\\server01\profiles"
#Get User Folder names into variable for ForEach Loop
$UserFolders = get-childitem -path $path\*.V2 | where-object {$_.Psiscontainer -eq "True"} |select-object name
#Loop through folders in Directory
foreach ($UserFolder in $UserFolders){
#remove the last .V2 from the folder name
$UserFolder = $UserFolder.name.substring(0,$UserFolder.name.length-3)
write-output $path\$userfolder
test-path $path\$userfolder #returns True or false
}
I just cant get the last bit to work. How can I only display only those folders that exist (return True)
You just need to rearrange things so that Write-Output only occurs if Test-Path validates that a path exists. I won't add anything new to your code except for an if statement, as an example:
foreach ($UserFolder in $UserFolders){
$UserFolder = $UserFolder.name.substring(0,$UserFolder.name.length-3)
if (test-path $path\$userfolder)
{
# Code at this level will only be executed if Test-Path was true.
write-output $path\$userfolder
}
}
So by placing write-output into the scope of the if statement, we ensure that it will only be executed if Test-Path is true.

How to use an array in a zip function using powershell?

I am still pretty new to scripting and "programming" at all. if you miss any information here let me know.
This is my working zip function:
$folder = "C:\zipthis\"
$destinationFilePath = "C:\_archive\zipped"
function create-7zip{
param([string] $folder,
[String] $destinationFilePath)
write-host $folder $destinationFilePath
[string]$pathToZipExe = "C:\Program Files (x86)\7-Zip\7zG.exe";
[Array]$arguments = "a", "-tzip", "$destinationFilePath", "$folder";
& $pathToZipExe $arguments;
}
Get-ChildItem $folder | ? { $_.PSIsContainer} | % {
write-host $_.BaseName $_.Name;
$dest= [System.String]::Concat($destPath,$_.Name,".zip");
(create-7zip $_.FullName $dest)
}
create-7zip $folder $destinationFilePath
now I want him to zip special folders which I already sorted out :
get-childitem "C:\zipme\" | where-Object {$_.name -eq "www" -or $_.name -eq "sql" -or $_.name -eq "services"}
This small function finds the 3 folders I need called www, sql and services. But I didn't manage to insert this into my zip function, so that exactly this folders are zipped and put into C:\_archive\zipped
Because a string is used instead of an array, he tried always to look for a folder called wwwsqlservice which is not there. I tried to put an array using #(www,sql,services) but i had no success, so whats the right way, if there is one?
It should compatible with powershell 2.0, no ps3.0 cmdlets or functions please.
thanks in advance!
Here's a really simple example of what you want to do, removed from the context of your function. It assumes that your destination folders already exist (You can just use Test-Path and New-Item to create them if they don't), and that you're using 7z.exe.
$directories = #("www","sql","services")
$archiveType = "-tzip"
foreach($dir in $directories)
{
# Use $dir to update the destination each loop to prevent overwrites!
$sourceFilePath = "mySourcePath\$dir"
$destinationFilePath = "myTargetPath\$dir"
cmd /c "$pathToZipExe a $archiveType $destinationFilePath $sourceFilePath"
}
Overall it looks like you got pretty close to a solution, with some minor changes needed to support the foreach loop. If you're confident that create-7zip works fine for a single folder, you can substitute that for the cmd /c line above. Here's a listing of some handy example usages for 7zip on the command line.

How many ways to check if a script was "successful" by using Powershell?

I am still very new and I have for example one script to backup some folders by zipping and copying them to a newly created folder.
Now I want to know if the zip and copy process was successful, by successful i mean if my computer zipped and copied it. I don't want to check the content, so I assume that my script took the right folders and zipped them.
Here is my script :
$backupversion = "1.65"
# declare variables for zip
$folder = "C:\com\services" , "C:\com\www"
$destPath = "C:\com\backup\$backupversion\"
# Create Folder for the zipped services
New-Item -ItemType directory -Path "$destPath"
#Define zip function
function create-7zip{
param([String] $folder,
[String] $destinationFilePath)
write-host $folder $destinationFilePath
[string]$pathToZipExe = "C:\Program Files (x86)\7-Zip\7zG.exe";
[Array]$arguments = "a", "-tzip", "$destinationFilePath", "$folder";
& $pathToZipExe $arguments;
}
Get-ChildItem $folder | ? { $_.PSIsContainer} | % {
write-host $_.BaseName $_.Name;
$dest= [System.String]::Concat($destPath,$_.Name,".zip");
(create-7zip $_.FullName $dest)
}
Now I can either check if in the parentfolder is a newly created folder by time.
Or i can check if there are zip folders in my subfolders I created.
What way would you suggest? I probably just know this ways, but there are a million way to do this.
Whats your idea? The only rule is , that powershell should be used.
thanks in advance
You could try using the Try and Catch method by wrapping the (create-7zip $_.FullName $dest) with a try and then catch any errors:
Try{ (create-7zip $_.FullName $dest) }
Catch{ Write-Host $error[0] }
This will Try the function create-7zip and write any the errors that many accrue to the shell.
One thing that can be tried is checking the $? variable for the status of the command.
$? stores the status of the last command run,
So for
create-7zip $_.FullName $dest
If you then echo out $? you will see either true or false.
Another option is the $error variable
You can also combine these in all sorts of ways (Or with the exception handling).
For example, run your command
foreach-object {
create-7zip $_.FullName $dest
if (!$?) {"$_.FullName $ErrorVariable" | out-file Errors.txt}
}
That script is more pseudocode for ideas than working code, but it should at least get you close to using it!