Check Which Path exists and IF...Test-path PS - powershell

Actual File Configuration:
clustername=GLA-CLU2
fswmain=\DC01\SQL-FSW1
fswdr=\DC01\SQL-FSW2
My actual script:
### BEGIN OF Passing as Variables, the configuration values separated with '=' and Retrieved from the indicated TXT file:
Get-Content '.\FSW_pathConf.txt' | Foreach-Object {
$Vconfvalue = $_.Split('=')
New-Variable -Name $Vconfvalue[0] -Value $Vconfvalue[1] }
### END OF Passing values as Variables
### Testing Each Path defined into configuration file
$currentfsw = Get-clusterresource -cluster $clustername | where-object {$_.ResourceType -like "File Share Witness"} | get-clusterparameter -Name "sharepath" | Select Value
Write-Host "`r"
Write-Host "the current file share witness configuration On Cluster: '$($Clustername)' is: '$($currentfsw)' "
if($currentfsw -is "$fswmain") {Test-Path -Path "$fswmain" -IsValid}
else{Set-ClusterQuorum -Cluster $Clustername -NodeAndFileShareMajority "$fswdr"}
if($currentfsw -is "$fswdr") { Test-Path -Path "$fswdr" -IsValid}
else{Set-ClusterQuorum -Cluster $Clustername -NodeAndFileShareMajority "$fswmain" }
What I would like to do whcih im struggling with:
if $fswmain is valid then return "OK,current fsw is working" and stop this script here
If not $currentfsw is no valid then run the command below to swith to $fswdr
Then, only if $currentfsw is not equal to $fswmain
if $fswdr is valid then return "OK,current fsw is working" and stop this script here
If not run the command below to switch to $fswmain
Any could bring some help here ? I am quite new with powershell and sysadmin
Thank you.

Related

Powershell Throw Causing Variables to Clear?

My PowerShell script just checks multiple servers to make sure the input* and output* directories are clear of any files.
I'm simply trying to output to console the results of a GCI call prior to throwing an error message. However, when I uncomment the "throw" line, the $inputFiles and $outputFiles no longer output to the console. Below is the code:
$allServers = #(
"server1.com",
"server2.com")
foreach ($server in $allServers) {
$inputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\input*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
$outputFiles = Get-ChildItem -Path "\\$server\C$\jobs\statements\output*\" -Recurse | Where-Object {! $_.PSIsContainer } | Select FullName
if ($inputFiles -eq $NULL -and $outputFiles -eq $NULL) {
Write-Host "Environment is ready for statement processing."
}
else {
Write-Host "Environment is NOT ready for statement processing."
Write-Host "The following files exist in input/output: `n"
$inputFiles
$outputFiles
#Throw "Files exist in input/output. See above for details."
}
}
Below is the console output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Environment is NOT ready for statement processing.
The following files exist in input/output:
FullName
--------
\\server1.com\C$\jobs\statements\input\asdasd.txt
\\server1.com\C$\jobs\statements\input_254\asdasd.txt
\\server1.com\C$\jobs\statements\input_test\asdasd.txt
\\server2.com\C$\jobs\statements\input\CUSSTAT10302021.245
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021
\\server2.com\C$\jobs\statements\input\CUSSTAT11312021.zip
And below is the console output when I uncomment the "throw" line:
Environment is NOT ready for statement processing.
The following files exist in input/output:
Files exist in input/output. See above for details.
At C:\jobs\statements\bin\Statements-EnvironmentCheck.ps1:47 char:9
+ Throw "Files exist in input/output. See above for details."
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (Files exist in ...ve for details.:String) [], RuntimeException
+ FullyQualifiedErrorId : Files exist in input/output. See above for details.
I know I have some error output cleanup to perform in order to include all the servers that might have files present, but please ignore that for now.
What you're experiencing is explained in this answer and this answer, basically you need to implement Out-Host \ Out-Default:
$inputFiles, $outputFiles | Out-Host # Should fix the problem
# possibly `throw` might require this too
throw "Files exist in input/output. See above for details." | Out-Host
However, I feel is worth showing you a better way to approach your code, returning a unified array of objects which you can filter, sort and export.
$allServers = #(
"server1.com"
"server2.com"
)
$result = foreach ($server in $allServers) {
# use `-File` instead of `! $_.PSIsContainer`
$out = #{
in = Get-ChildItem "\\$server\C$\jobs\statements\input*\" -Recurse -File
out = Get-ChildItem "\\$server\C$\jobs\statements\output*\" -Recurse -File
}
# if $out['in'] and $out['out'] are `$null`, Ready is `$true`
[pscustomobject]#{
Ready = -not($out['in'] -or $out['out'])
Server = $server
Files = $out
}
}
Now, if you want to see which servers are Ready (no files in input and output):
$result.where{ $_.Ready }
And if you want to see which servers are not Ready, and have a list of the files:
$result.where{ -not $_.Ready }.foreach{
foreach($file in $_.Files.PSBase.Values.FullName) {
[pscustomobject]#{
Server = $_.Server
Files = $file
}
}
}

Powershell - Get desktop path for all users [OneDrive Sync on some of them]

I am trying to search all user's desktops for a particular shortcut and I find difficulties enumerate all desktop paths for different users on the computer as some of them have OneDrive sync and the standard path c:\Users\%user%\Desktop is not to be found.
I have tried getting the path with the GetFolderPath which only returns the path to the current user:
[System.Environment]::GetFolderPath("Desktop")
So briefly the path scenarios are:
C:\users\username\Desktop
C:\users\username\One Drive - Company\Desktop
I would be glad if somebody has a hint how to find all paths in this mixed environment.
Here's my older training script. I don't know how (or if any) it works with OneDrive cync as I have OneDrive disabled (or even uninstalled) because I found it extremely irritating…
Remove-Variable path -ErrorAction SilentlyContinue
Write-Verbose "--- Special Folders ---" -Verbose
$SpecialFolders = #{}
$names = [Environment+SpecialFolder]::GetNames( [Environment+SpecialFolder])
ForEach ($name in $names) {
# assign and then check
if( $path = [Environment]::GetFolderPath($name) ){
$SpecialFolders[$name] = $path
} else {
Write-Warning $name
$SpecialFolders[$name] = ''
}
}
$SpecialFolders.GetEnumerator() |
Sort-Object -Property name #| Format-Table -AutoSize
"---"
###Pause
$ShellFolders=#{}
Write-Verbose "--- Shell Folders ---" -Verbose
[System.Enum]::GetValues([System.Environment+SpecialFolder]) |
ForEach-Object {
$ShellFolders[$_.ToString()] =
($_.value__, [System.Environment]::GetFolderPath($_))
}
$ShellFolders.GetEnumerator() |
Sort-Object -Property name # | Format-Table -AutoSize

Hidden variable Password parameter - powershell 4.0

I am creating a release definition with a powershell script to replace a file with env variables from the release definition it works but It doesn't seem to catch the password variable which is hidden in the release definition. is there a way to tell powershell to look for hidden variables?
UPDATE: Here is the script it finds all the variables in $paramsFilePath that are not hidden my password in In environmental variables in Release definition is hidden and the script doesn't find it.
param(
[string]$paramsFilePath,
)
Write-Verbose -Verbose "Entering script Replace-SetParameters.ps1"
Write-Verbose -Verbose ("Path to SetParametersFile: {0}" -f $paramsFilePath)
# get the environment variables
$vars = Get-ChildItem -path env:*
# read in the setParameters file
$contents = Get-Content -Path $paramsFilePath
# perform a regex replacement
$newContents = "";
$contents | % {
$line = $_
if ($_ -match "__(\w+)__") {
$setting = Get-ChildItem -path env:* | ? { $_.Name -eq $Matches[1] }
if ($setting) {
Write-Verbose -Verbose ("Replacing key {0} with value from environment" -f $setting.Name)
$line = $_ -replace "__(\w+)__", $setting.Value
}
}
$newContents += $line + [Environment]::NewLine
}
Write-Verbose -Verbose "Overwriting SetParameters file with new values"
Set-Content $paramsFilePath -Value $newContents
Write-Verbose -Verbose "Exiting script Replace-SetParameters.ps1"
Unlike the normal variable, the password you are trying to get is secret variable.
Secret Variables
We recommend that you make the variable Secret if it contains a
password, keys, or some other kind of data that you need to avoid
exposing.
The variable replacement we do is on the inputs on the tasks, we don't parse the scripts. To use secret variables you will have to take those as inputs into your script we explicitly do not populate those into the environment. You could take a look at this discuss: Use hidden / secret variables in commands

writing output file as .txt or .csv to script containing multiple conditions

I have written a script which checks a service status, tests two paths and also tests a registry value. Currently I am getting output on the power shell console (that could be because I am using write-output command).
Is there any way to write the single one page output to a file?
I am struggling to find a way to out-file entire output to a file.
Below is the script.
$testpath = Test-Path "C:\test"
$testpath2 = test-path "C:\test"
$mcshieldk = Get-Service -Name mcshield | select Name
$internet = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\internet explorer").MkEnabled $hostname = hostname Write-Host "hostname of comuter is" $hostname if (Test-Path $Machinetype)
{}
else { Write-Host "internet is" $internet }
if ($testpath -eq $true -and $testpath2 -eq $true)
{ Write-Host "test and test1 folder exists" -ForegroundColor Green }
else{ Write-Host "folder does not exists" -ForegroundColor Red } if($mcshield.Name -eq "mcshield") { Write-Host "mcshield service exists" }
else { Write-Host "mcshield does not exists" }
Below is the console output
hostname of comuter is Server1
internet is Yes
test and test1 folder exists
mcshield does not exists
Swap out your Write-Host cmdlets or add in another line with the following:
"Your output text $YourVariable" | Out-File -FilePath "C:\Log.txt" -Append -Encoding utf8
This will append a string to the end of the log file C:\Log.txt. Note, missing the -Append parameter will cause the file to be overwritten.
You can also use the follow to give the same affect:
"Your output text $YourVariable" >> "C:\Log.txt"
But be carefully not to mix the two methods as you might get encoding errors in the text file. If you wish to overwrite the file with the second method use > instead of >>.

Save powershell script after entering details for read-host

Example:
$nameofpath = read-host "enter path"
get-services | export-csv "$nameofpath"
I want a script so after entering a path such as c:\files\test.txt in the example above, it will save a script with:
get-services | export-csv "c:\files\test.txt"
... so I could go to that file click it and it will run.
At the moment I have an draft script like this but if I know how to do the first example I should hopefully be able to do the same for that
You'd either need to change the script that you're running, or query some other text file. If there is anything in the text file, use that; otherwise, prompt for the value. Here's an example of how you could change the script you're running using the $PSCommandPath (it's an automatic variable that contains the full path and file name of the script that is being run) variable:
$Foo = $null
#If $Foo is $null prompt for value then write that value to the script.
if($Foo -eq $null){
$Foo = Read-Host "Foo"
#Need to becarful not to match this line
$NewScript = Get-Content $PSCommandPath | ForEach-Object {$_ -replace '^\$Foo = \$null$',"`$Foo = '$Foo'"}
$NewScript | Out-File $PSCommandPath -Force
}
Write-Host "Foo $Foo"
Hope this helps.
This looks amateur but works as expected
$path = [Microsoft.VisualBasic.Interaction]::InputBox("Enter path")
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null
get-service | export-csv -path $path\services.csv # original command
$Command="get-service | export-csv -path $path\services.csv" # same copy here to save
$command |Out-File "D:\exportservice.ps1" # where you want the file to be saved to run later