How to capture $false in ValidateScript() - powershell-4.0

I have a function that validates user input and it works as expected. Returns $true when correct and Throws an error when not.
Since I would like to return the results (True and False) to be used elsewhere, Is it possible to capture $false from ValidateScript()?
Tried various operations like if/else and tried searching but did not find anything relevant.
function Check-Input-ShareName {
[CmdletBinding()]
Param(
[Parameter(Mandatory)]
[ValidateNotNullOrEmpty()]
[ValidateScript({
if ($_ -match '(?=^[a-zA-Z].{3,30}$)(?![_-].+)(?!.+[_-]$)(?!.*[_-]{2,})[^<>[\]{}|\\\/^~%# :;_,$#%*?\0-\cZ]+$') {
$true
} else {
#Throw "$_ is invalid Share Name." this works and throws error when I uncomment
$false
}
})]
[string]$ShareName
)
Process {
if ($true) {
Write-Host 'True'
return $ShareName
}
if ($false) {
Write-Host 'True'
return 'invalid'
}
I would like if its false to return false so I can take action on that elsewhere.

Related

File does not exist (but it's there) and Multiple ambiguous overloads found for "AddPicture" and the argument count: "2"

I'm trying to add an image to an excel worksheet with powershell 5. and VSCode.
I get these errors:
C:\CC_SnapViews\EndToEnd_view\path is correct\file.bmp
does not exist (but it's there)
Multiple ambiguous overloads found for "AddPicture" and the argument
count: "2"
When I search the internet, this error isn't coming up in the search. I was following these examples:
addPicture
addPicture github
This is my code:
$xlsx = $result | Export-Excel -Path $outFilePath -WorksheetName $errCode -Autosize -AutoFilter -FreezeTopRow -BoldTopRow -PassThru # -ClearSheet can't ClearSheet every time or it clears previous data ###left off
$ws = $xlsx.Workbook.Worksheets[$errCode]
for ($row = 2 ;( $row -le $tempRowCount ); $row++)
{
#Write-Host $($ws.Dimension.Rows)
#Write-Host $($row)
$ws.Row($row).Height
$ws.Row($row).Height = 150
$ws.Row($row)[3]
$result.GetValue($row) #$ws.Row($row)[3]
$pictureName=$result[$row].PictureID
$pictureNamePath=$result[$row].ImageFileName
#place the image in spreadsheet
#https://github.com/dfinke/ImportExcel/issues/1041 https://github.com/dfinke/ImportExcel/issues/993
$drawingName = "$($pictureName)_Col3_$($row)" #Name_ColumnIndex_RowIndex
#Write-Host $image
Write-Host $drawingName
####
if($null -ne $pictureNamePath)
{
$image = Get-Image -imageFileName $pictureNamePath ###error pictureNamePath does not exist but it does
}
else
{
Write-Host "Did not find an image file for $pictureName in $pictureNamePath"
}
$picture = $ws.Drawings.AddPicture($pictureNamePath,$image) ###error message here
}
Any ideas why powershell thinks the image file doesn't exist?
Update:
I added some debug in the foreach for the rows:
for ($row = 2 ;( $row -le $tempRowCount ); $row++)
{
#Write-Host $($ws.Dimension.Rows)
#Write-Host $($row)
$ws.Row($row).Height
$ws.Row($row).Height = 150
$ws.Row($row)[3]
$result.GetValue($row) #prints entire row info
$pictureName=$result[$row].PictureID
$pictureNamePath=$result[$row].ImageFileName
if(Test-Path $pictureNamePath)
{
Write-Host "$($pictureNamePath) exists" ##prints ...filenamepath... exists (looks good)
}
Write-Host "pic path = $pictureNamePath" ##prints pic path = ..file name path... (looks good)
...
Update2:
Adding the Get-Image function:
Function Get-Image{
[cmdletbinding()]
Param ([string]$imageFileName)
Process
{
#find image file name to look for
if($imageFileName.Exists) #if($imageFile2.Exists)
{
[System.Drawing.Image] $image = [System.Drawing.Image]::FromFile($imageFileName) #may not need this step
#need to figure out which is correct if there's multiple images
return $image
}
else {
Write-Host "$($imageFileName) does not exist"
return $null
}
} #end Process
}# End of Function
I changed my function to use Test-Path instead and it sets the image now.
Function Get-Image{
[cmdletbinding()]
Param ([string]$imageFileName)
Process
{
#find image file name to look for
if(Test-Path $imageFileName) ###instead of Exists
{
[System.Drawing.Image] $image = [System.Drawing.Image]::FromFile($imageFileName) #may not need this step
#need to figure out which is correct if there's multiple images
return $image
}
else {
Write-Host "$($imageFileName) does not exist"
return $null
}
} #end Process
}# End of Function

PowerShell Scipt for adding new Credentials

I'm trying to make script to automaticly assign credidentials based on the group that was chose. I'm getting a lot of syntax errors. Can you help?
Function Add-OSCCredential
{
$target = Read-Host "Group number"
If($target)
{
If($target -eq 1)
{[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1}
[ElseIf($target -eq 2)
{[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2}]
{
[ElseIf($target -eq 3)
{[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3}]
{
If($result -match "The command line parameters are incorrect")
{Write-Error "Failed to add Windows Credential to Windows vault."}
ElseIf($result -match "CMDKEY: Credential added successfully")
{Write-Host "Credential added successfully."}
}
Else
{
Write-Error "Internet(network address) or username can not be empty,please try again."
Add-OSCCredential
}
}
Add-OSCCredential
I'd suggest you use a proper editor such as vscode which will give you lots of hints concerning bad syntax.
In your case there are a lot of [] and {} parenthesis that do not make sense.
Only considering the syntax of that function, the following should 'work':
Function Add-OSCCredential {
$target = Read-Host "Group number"
If ($target) {
If ($target -eq 1) {
[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1
}
ElseIf ($target -eq 2) {
[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2
}
ElseIf ($target -eq 3) {
[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3
}
If ($result -match "The command line parameters are incorrect") {
Write-Error "Failed to add Windows Credential to Windows vault."
}
ElseIf ($result -match "CMDKEY: Credential added successfully") {
Write-Host "Credential added successfully."
}
}
Else {
Write-Error "Internet(network address) or username can not be empty,please try again."
Add-OSCCredential
}
}
edit:
you'd most likely want to look into a ready-to-use PowerShell Module such as CredentialManager, this way you wouldn't have to fiddle with cmdkey.exe yourself.
The returned value for Read-Host is always a string, but you treat it like an integer in your tests.
For better readability, I suggest using a switch rather that yet another set of if..elseif..else statements.
Something like this:
function Add-OSCCredential {
$target = Read-Host "Enter Group number (1-3)"
if ($target -match '1|2|3') {
switch ([int]$target) {
1 {[string]$result = cmdkey /add:Group1 /user:Group1 /pass:Pass1}
2 {[string]$result = cmdkey /add:Group2 /user:Group2 /pass:Pass2}
3 {[string]$result = cmdkey /add:Group3 /user:Group3 /pass:Pass3}
}
if($result -match "The command line parameters are incorrect") {
Write-Error "Failed to add Windows Credential to Windows vault."
}
elseif ($result -match "Credential added successfully") {
Write-Host "Credential added successfully."
}
else {
Write-Warning $result
}
}
else {
Write-Warning "Group number must be either 1, 2 or 3. Please try again."
Add-OSCCredential
}
}
Add-OSCCredential

Powershell - check if file exist and contains string pattern

wrote this small part of code to check if file exist and contains string pattern
try {
$SEL = Select-String -Path \\$serversPing\c$\Scripts\compare_result.txt -Pattern "no differences encountered" -ErrorAction SilentlyCOntinue
}catch{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
}
Finally {
if ($SEL | Test-Path -ErrorAction SilentlyContinue){
#write-host $serversPing $SEL.Pattern
#write-host $serversPing $SEL
if ($SEL.Pattern -eq "no differences encountered")
{
$SoftCheckResult = "ok"
}
else
{
$SoftCheckResult ="Verify"
}
}
else{
$SoftCheckResult = "NotInScope"
}
}
But, it does not do what it should. First of all it partially recognize that path exist and secondly it does partially recognize pattern in txt file. Can you please help me?
I suspect that PATTER is partially recognizable on multiply server.(whitepaces etc) even so how to skip that?
Strange think is that it does not see that pattern is missing in file, it return
NotinScope instead Verify
Below file without this pattern
And below you can see normal pattern
Since you use plural in $serversPing, I suspect this variable comes from an earlier part of your code and contains a COLLECTION of servers.
I would change the order of checks and start with a test to see if the file exists on that server or not:
# As you mentioned a possible whitespace problem the pattern below uses regex `\s+` so multiple whitespace characters are allowed betwen the words.
$pattern = "no\s+differences\s+encountered"
foreach ($server in $serversPing) {
if (Test-Connection $server -Count 1 -Quiet) {
$filePath = Join-Path -Path "\\$server" -ChildPath 'c$\Scripts\compare_result.txt'
if (Test-Path $filePath -PathType Leaf) {
# -Quiet: Indicates that the cmdlet returns a Boolean value (True or False), instead of a MatchInfo object.
# The value is True if the pattern is found; otherwise, the value is False.
if (Select-String -Path $filePath -Pattern $pattern -Quiet) {
Write-Host "Pattern '$pattern' found in '$filePath'"
$SoftCheckResult = "ok"
}
else {
Write-Host "Pattern '$pattern' not found in '$filePath'"
$SoftCheckResult = "Verify"
}
}
else {
Write-Host "File '$filePath' not found"
$SoftCheckResult ="NotInScope"
}
}
else {
Write-Host "Server '$server' is off-line."
$SoftCheckResult ="OffLine"
}
}
I added a Test-Connection in the foreach loop to first see if the server is online or not. If you have checked that before and the $serversPing variable contains only servers that are online and reachable, you may skip that.
Concerning the -Path of the Select-String cmdlet, you should put the value between "" :
$SEL = Select-String -Path "\\$serversPing\c$\Scripts\compare_result.txt" -Pattern "no differences encountered" -ErrorAction SilentlyCOntinue
EDIT
This should do the trick :
try {
$SEL = Select-String -Path \\$serversPing\c$\Scripts\compare_result.txt -Pattern "no differences encountered" -ErrorAction SilentlyCOntinue
}catch{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
}
Finally {
if ($SEL){
$SoftCheckResult = "ok"
}
else
{
$SoftCheckResult ="Verify"
}
}
try
{
$SEL = $null
$SEL = Select-String -Path \\$serversPing\c$\Scripts\compare_result.txt -Pattern "no differences encountered" -ErrorAction Stop
if ($SEL)
{
$SoftCheckResult = "ok"
}
else
{
$SoftCheckResult = "Verify"
}
}
catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
$SoftCheckResult = "NotInScope"
}
return $softCheckResult
Please try like below :
$SEL = "Fiile path location"
if ($SEL | Test-Path -ErrorAction SilentlyContinue){
if ($SEL Get-Content | Select-String -pattern "no differences encountered")
{
}
....
}

Adding a deployment step to call a http endpoint in Octopus Deploy

I am trying to create a new Octopus deploy step, which will call a http endpoint.
I have found the following step type that seems promising, but can get any documentation on it:
"Http Json Value Check
Gets json from http endpoint, looks-up a value by key and checks that it matches a predefined value. If value matches then script exists with a success code, if value does not match then script exists with a failure code."
I am not sure what to enter for the:
"Json Key" and the "Expected Value"
Has anyone done this? have an example or suggest a different method to achieve what I am trying?
Here is a PowerShell script I use to get the JSON from an endpoint and check for a valid Value. If I could remember where I got the code base before I modified it a little I would give credit to the original author. It will work with either a string or a regex.
#-------------------------------------------------------------------------
# Warmup.ps1
#-------------------------------------------------------------------------
[int]$returnme = 0
[int]$SleepTime = 5
[string]$regex = '[>"]?[aA]vailable["<]?'
[string]$strContains = $regex
# [string]$strContains = "log in"
[string]$hostName = hostname
[string]$domainName = (Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .).DNSDomain
[string]$warmMeUp = "http://$hostName.$domainName/endpoint"
[string]$html = "Will Be Set Later"
#-------------------------------------------------------------------------
# Get-WebPage
#-------------------------------------------------------------------------
function Get-WebPage([string]$url)
{
try
{
$wc = new-object net.webclient;
$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials;
[string]$pageContents = $wc.DownloadString($url);
$wc.Dispose();
}
catch
{
Write-Host "First Try Failed. Second Try in $SleepTime Seconds."
try
{
Start-Sleep -s $SleepTime
$wc = new-object net.webclient;
$wc.credentials = [System.Net.CredentialCache]::DefaultCredentials;
$pageContents = $wc.DownloadString($url);
$wc.Dispose();
}
catch
{
$pageContents = GetWebSiteStatusCode($url)
}
}
return $pageContents;
}
#-------------------------------------------------------------------------
# GetWebSiteStatusCode
#-------------------------------------------------------------------------
function GetWebSiteStatusCode
{
param (
[string] $testUri,
[int] $maximumRedirection = 5
)
$request = $null
try {
$request = Invoke-WebRequest -Uri $testUri -MaximumRedirection $maximumRedirection -ErrorAction SilentlyContinue
}
catch [System.Net.WebException] {
$request = $_.ErrorDetails.Message
}
catch {
Write-Error $_.Exception
return $null
}
return $request
}
#-------------------------------------------------------------------------
# Main Application Logic
#-------------------------------------------------------------------------
"Warming up '{0}'..." -F $warmMeUp;
$html = Get-WebPage -url $warmMeUp;
Write-Host "Looking for Pattern $strContains"
if ($html.ToLower().Contains("unavailable") -or !($html -match $strContains))
{
$returnme = -1
Write-Host "Warm Up Failed. html returned:`n" + $html
}
exit $returnme

Retrieve the Windows Identity of the AppPool running a WCF Service

I need to verify that the underlying server-side account running my WCF Service has correct ACL permissions to various points on the local file system. If I can get the underlying Windows Identity, I can take it from there. This folds into a larger Powershell script used after deployment.
Below is my powershell snippet, that get the ApplicationPoolSid, how do you map this to the AppPool's Windows Identity?
$mywcfsrv = Get-Item IIS:\AppPools\<MyWCFServiceName>;
Updated below to include Keith's snippet
For completeness, here's the solution:
Function Get-WebAppPoolAccount
{
param ( [Parameter(Mandatory = $true, Position = 0)]
[string]
$AppPoolName )
# Make sure WebAdmin module is loaded.
$module = (Get-Module -ListAvailable) | ForEach-Object { if ($_.Name -like 'WebAdministration') { $_ } };
if ($module -eq $null)
{
throw "WebAdministration PSSnapin module is not available. This module is required in order to interact with WCF Services.";
}
Import-Module $module;
# Get the service account.
try
{
$mywcfsrv = Get-Item (Join-Path "IIS:\AppPools" $AppPoolName);
}
catch [System.Exception]
{
throw "Unable to locate $AppPoolName in IIS. Verify it is installed and running.";
}
$accountType = $mywcfsrv.processModel.identityType;
$account = $null;
if ($accountType -eq 'LocalSystem')
{
$account = 'NT AUTHORITY\SYSTEM';
}
elseif ($accountType -eq 'LocalService')
{
$account = 'NT AUTHORITY\LOCAL SERVICE';
}
elseif ($accountType -eq 'NetworkService')
{
$account = 'NT AUTHORITY\NETWORK SERVICE';
}
elseif ($accountType -eq 'SpecificUser')
{
$account = $mywcfsrv.processModel.userName;
}
return $account;
}
Like so:
$mywcfsrv = Get-Item IIS:\AppPools\<MyWCFServiceName>
$mywcfsrv.processModel.identityType

Resources