PowerShell hash-table return values - function

I have a simple script to return values from a hash table:
param
(
[Parameter(Mandatory = $true)]
[string]$Name
)
function getvalues ($Name) {
$nameList= #{"CFT"=#{"name1"="text1"; "name2"="text2"}}
#return $nameList[$Name]
return ,$nameList
}
$Values = getvalues($Name)
Write-Debug "DEBUG: Name1 = "$Values["name1"]
Write-Debug "DEBUG: Name2 = "$Values["name2"]
When I run it, I get the following error:
Write-Debug : A positional parameter cannot be found that accepts argument '$null'.
At C:\MSFT\add-test.ps1:21 char:2
+ write-Debug "DEBUG: Name1 = "$Values["name1"]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-Debug], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteDebugCommand
Write-Debug : A positional parameter cannot be found that accepts argument '$null'.
At C:\MSFT\add-test.ps1:22 char:2
+ write-Debug "DEBUG: Name2 = "$Values["name2"]
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Write-Debug], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.WriteDebugCommand

You're terminating your strings and then using the $Values lookup. Either use a + or embed it into the string, or use the -f operator:
write-Debug ("DEBUG: Name1 = " + $Values["name1"])
write-Debug "DEBUG: Name2 = $($Values["name2"])"
write-Debug ("DEBUG: Name3 = {0}" -f $Values["name3"])
Note forms 1 and 3 need parentheses ( ).
Regarding your comment that there are no more errors and no output:
Are you sure your debug preference is set such that you can see the output? The point of Write-Debug and Write-Verbose is that you only see the output when the preference is set as such (and you shouldn't add DEBUG: in your string, it will be added for you). I suspect Write-Verbose is more appropriate for what you're doing.
To test quickly whether it will work, you can actually add -Debug or -Verbose as appropriate.
So for example:
Write-Verbose "Name2 = $($Values["name2"])" -Verbose

Related

How to get a value from powershell where the key has a dot at the beginning?

How do I get the value of a json where the key has "." at the beginning?
$json = '{".expires":"2022-10-13"}' | ConvertFrom-Json
cls
$json..expires #trying to get the value 2022-10-13
Error:
On the line:4 caractere:8
+ $json..expires
+ ~
You must provide a value expression after the '..' operator.
On the line:4 caractere:8
+ $json..expires
+ ~~~~~~~
Token 'expires' unexpected in the expression or statement.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpectedValueExpression
The code above gives error if I put a colon, is there another way?
You can enclose the property name in quotes.
$json.".expires"

"The property cannot be found on this object. Verify that the property exists." Property definitely exists

I can't figure out why I am not able to change these variables. If I type them into the console in debug mode, then it prints the values. It is also strange how I am able to change the allowedRequestors variable on line 24, but not any of the others. Does anyone know why this is happening to the other variables?
$FilePath = "C:\Users\Desktop\TestScripts\testBulkAP.csv"
$headers = & $PSScriptRoot\GetToken.ps1
## preparing create Catalog data
$accesspacakgeRequest = '{"displayName":"","description":"sddsds","isHidden":false,"catalogId":"","accessPackageResourceRoleScopes":[],"accessPackageAssignmentPolicies":[{"displayName":"Initial Policy","description":"Initial Policy","durationInDays":365,"expirationDateTime":null,"canExtend":false,"requestApprovalSettings":null,"accessReviewSettings":null,"notificationSettings":null,"additionalInfo":null,"isDenyPolicy":false,"id":"","activeAssignmentCount":0,"accessPackageId":"00000000-0000-0000-0000-000000000000","accessPackageCatalog":null,"createdDateTime":null,"modifiedDateTime":null,"createdBy":"","modifiedBy":"","countOfUsersIncludedInPolicy":null,"requestorSettings":{"acceptRequests":true,"scopeType":"NoSubjects","allowedRequestors":[],"isOnBehalfAllowed":false},"questions":[]}]}'
$emlRequestUrl = "https://graph.microsoft.com/beta/identityGovernance/entitlementManagement/accessPackages"
$accesspacakgeRequestObject = ConvertFrom-Json -InputObject $accesspacakgeRequest
$Content = Import-Csv $FilePath
foreach($assignmentData in $Content) {
$accesspacakgeRequestObject.catalogId = $assignmentData.catalogId
$accesspacakgeRequestObject.displayName = $assignmentData.displayName
$accesspacakgeRequestObject.description = $assignmentData.description
$accesspacakgeRequestObject.accessPackageAssignmentPolicies.requestorSettings.scopeType = $assignmentData.scope
if ($assignmentData.scope -eq "SpecificDirectorySubjects") {
$accesspacakgeRequestObject.accessPackageAssignmentPolicies.requestorSettings.allowedRequestors += New-Object -TypeName psobject -Property #{'#odata.type' = '#microsoft.graph.groupMembers'; 'id' = $assignmentData.groupId; 'description' = $assignmentData.groupName; 'isBackup' = 'false'}
}
$numApprovalStages = [int]$assignmentData.approvalStages
if ($numApprovalStages -gt 0) {
$accesspacakgeRequestObject.accessPackageAssignmentPolicies.requestApprovalSettings += New-Object -TypeName psobject -Property #{'approvalMode' = 'Serial'; 'isApprovalRequired' = 'true'; 'isApprovalRequiredForExtension' = 'false'; 'isRequestorJustificationRequired' = 'false'; 'approvalStages' = #()}
for ($i=1;$i -le [int]$assignmentData.approvalStages; $i++)
{
$accesspacakgeRequestObject.accessPackageAssignmentPolicies.requestApprovalSettings.approvalStages += New-Object -TypeName psobject -Property #{'approvalStageTimeOutInDays' = '14'; 'primaryApprovers' = #(); escalationApprovers = #();'isEscalationEnabled' = 'false'; 'escalationTimeInMinutes' = '0'; 'isApproverJustificationRequired' = 'true'}
$accesspacakgeRequestObject.accessPackageAssignmentPolicies.requestApprovalSettings.approvalStages.primaryApprovers += New-Object -TypeName psobject -Property #{'#odata.type' = '#microsoft.graph.singleUser'; "displayName" = ''; 'objectId' = Get-Variable -Name "assignmentData.approver$1" -ValueOnly; 'isBackup' = 'false'}
}
}
$requestbody = $accesspacakgeRequestObject | ConvertTo-Json -Depth 10
$response = Invoke-RestMethod $emlRequestUrl -Headers $headers -Method Post -Body $requestbody -UseBasicParsing -ErrorAction Continue
}
The error message is:
The property 'requestApprovalSettings' cannot be found on this object. Verify that the property exists and can be set.
At C:\Users\Desktop\TestScripts\AddAccessPackageAndPolicyWITHAPPROVER.ps1:30 char:5
+ $accesspacakgeRequestObject.accessPackageAssignmentPolicies.reque ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyAssignmentException
The property 'approvalStages' cannot be found on this object. Verify that the property exists and can be set.
At C:\Users\Desktop\TestScripts\AddAccessPackageAndPolicyWITHAPPROVER.ps1:34 char:9
+ $accesspacakgeRequestObject.accessPackageAssignmentPolicies.r ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
Get-Variable : Cannot find a variable with the name 'assignmentData.approver1'.
At C:\Users\Desktop\TestScripts\AddAccessPackageAndPolicyWITHAPPROVER.ps1:35 char:250
+ ... objectId' = Get-Variable -Name "assignmentData.approver$i" -ValueOnly ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (assignmentData.approver1:String) [Get-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand
The property 'primaryApprovers' cannot be found on this object. Verify that the property exists and can be set.
At C:\Users\Desktop\TestScripts\AddAccessPackageAndPolicyWITHAPPROVER.ps1:35 char:250
+ ... objectId' = Get-Variable -Name "assignmentData.approver$i" -ValueOnly ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
The .accessPackageAssignmentPolicies property contains an array ([...]-enclosed in the JSON input).
Even though that array happens to contain only one element, you still need to access it by index in order to set its (only) element's properties; e.g.:
# Note the `[0]`
$accesspacakgeRequestObject.accessPackageAssignmentPolicies[0].requestorSettings.scopeType = $assignmentData.scope
Note that getting properties does not strictly require this index access, because of a feature called member-access enumeration.
This perhaps surprising asymmetry - requiring indexed access on setting - is by design, however - see this answer for more information.

New-ADUser is not working properly when bulk loading via .csv file

I'm running into an error where this is not picking up the password field at all... I ran the import command manually to make sure it was grabbing all of the correct data, but it errors out on the password and group info...
$Users = Import-Csv -Path "C:\NewUsers.csv"
foreach ($User in $Users)
{
$Displayname = $User.'Firstname' + " " + $User.'Lastname'
$UserFirstname = $User.'Firstname'
$UserLastname = $User.'Lastname'
$OU = $User.'OU'
$SAM = $User.'SAM'
$UPN = $User.'Firstname' + "." + $User.'Lastname' + "#" + $User.'Maildomain'
$Password = $User.'Password'
$Description = $User.'Description'
$Group = $User.'Group'
$Account = New-ADUser -Name "$Displayname" -DisplayName "$Displayname" -SamAccountName $SAM -UserPrincipalName $UPN -GivenName "$UserFirstname" -Surname "$UserLastname" -Description "$Description" -AccountPassword (ConvertTo-SecureString $Password -AsPlainText -Force) -Enabled $true -Path "$OU" -ChangePasswordAtLogon $false -PasswordNeverExpires $true -server esg.intl -PassThru
Add-ADGroupMember -Identity $Group -Members $Account
}
And here are the errors I'm getting even though I know the passwords are ok:
New-ADUser : The password does not meet the length, complexity, or history requirement of the domain.
At C:\Users\A-Shane.Johnson\Desktop\Bulk Add Domain Users.ps1:24 char:13
+ ... $Account = New-ADUser -Name "$Displayname" -DisplayName "$Displaynam ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (CN=ESGAP PMOInt...,DC=esg,DC=intl:String) [New-ADUser], ADPasswordComplexi
tyException
+ FullyQualifiedErrorId : ActiveDirectoryServer:1325,Microsoft.ActiveDirectory.Management.Commands.NewADUser
Add-ADGroupMember : Cannot validate argument on parameter 'Members'. The argument is null or empty. Provide an
argument that is not null or empty, and then try the command again.
At C:\Users\A-Shane.Johnson\Desktop\Bulk Add Domain Users.ps1:26 char:46
+ Add-ADGroupMember -Identity $Group -Members $Account
+ ~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Add-ADGroupMember], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.AddADGrou
pMember
Depending on how that CSV is generated you might try double checking that there isn't an extra space in the Password column header? i.e. 'Password '. Sometimes that trips me up because it doesn't show in the excel or cmd line view easily.
I found the problem and answer. Apparently our domain has an issue when part of the username is in the password. I misunderstood that error thinking that the conversion is what was causing the issue...
I fixed the passwords and now the script runs beautifully!

Problems in reading a commandline json object using powershell

I have a powershell script "test.ps1" which takes a json string as a command line input & tries to parse it.
The powershell script is as below -
param(
[string]$json = $(throw 'test')
)
$currentPath = Get-Location
[Reflection.Assembly]::LoadFile("$currentPath\Newtonsoft.Json.dll")
$result = [Newtonsoft.Json.Linq.JObject]::Parse($json)
foreach($unit in $result["DevResults"]) {Write-Host $unit.TechnologyName.ToString()}
But it is giving me the below error -
PS C:\Users\aghosh.RJFDEV\Documents> ./test.ps1 '{"DevResults":[{"TechnologyName":"TFS","RuleName":"Alt CI ID for ESB","OutputValue":"ESClientCenter"},{"TechnologyName":"TFS","RuleName":"TFS Team Project Name","OutputValue":"ClientCenter"}],"QaResults":[{"TechnologyName":"TFS","RuleName":"Alt CI ID for ESB","OutputValue":"ESClientCenter"},{"TechnologyName":"TFS","RuleName":"TFS Team Project Name","OutputValue":"ClientCenter"}],"PreProdResults":[{"TechnologyName":"TFS","RuleName":"Alt CI ID for ESB","OutputValue":"ESClientCenter"},{"TechnologyName":"TFS","RuleName":"TFS Team Project Name","OutputValue":"ClientCenter"}],"ProdResults":[{"TechnologyName":"TFS","RuleName":"Alt CI ID for ESB","OutputValue":"ESClientCenter"},{"TechnologyName":"TFS","RuleName":"TFS Team Project Name","OutputValue":"ClientCenter"},{"TechnologyName":"TFS","RuleName":"Process Template","OutputValue":"Raymond James CMMI V3.5"}]}'
GAC Version Location
--- ------- --------
False v2.0.50727 C:\Users\aghosh.RJFDEV\documents\Newtonsoft.Json.dll
You cannot call a method on a null-valued expression.
At C:\Users\aghosh.RJFDEV\Documents\test.ps1:13 char:82
+ foreach($unit in $result["DevResults"]) {Write-Host $unit.TechnologyName.ToString <<<< ()}
+ CategoryInfo : InvalidOperation: (ToString:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
You cannot call a method on a null-valued expression.
At C:\Users\aghosh.RJFDEV\Documents\test.ps1:13 char:82
+ foreach($unit in $result["DevResults"]) {Write-Host $unit.TechnologyName.ToString <<<< ()}
+ CategoryInfo : InvalidOperation: (ToString:String) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
My powershell version is 2.0 & the Json.Net library version is 3.5.
Please help me with the error or please suggest any other suitable approach.
Thanking in advance.
Change this line:
foreach($unit in $result["DevResults"]) {Write-Host $unit.TechnologyName.ToString()}
To this:
foreach($unit in $result["DevResults"]) {Write-Host $unit["TechnologyName"].ToString()}

How can I get powershell exception descriptions into a string?

I want to have access to the same message that Powershell prints when you send an error record to the output stream
Example:
This is the exception message At
C:\Documents and
Settings\BillBillington\Desktop\psTest\exThrower.ps1:1
char:6
+ throw <<<< (New-Object ArgumentException("This is the
exception"));
+ CategoryInfo : OperationStopped: (:) [],
ArgumentException
+ FullyQualifiedErrorId : This is the exception
I when a get the last ErrorRecord by doing $Error[0] I can't seem to figure out how to get this information in a simple way
I found this 'Resolve-Error' function from the community extensions here which does roughly what I want but it prints a huge semi-formatted list of stuff I don't need that I have to then strip
Is there way of accessing the message that Powershell uses or failing that a simpler way of getting hash of the values I care about so I can put them into a string in a format of my choosing?
How about:
$x = ($error[0] | out-string)
Is that what you wanted?
If you want a bit shorter message (more user friendly sometimes?) than #tomasr suggests this will do:
$error[0].ToString() + $error[0].InvocationInfo.PositionMessage
You will get something like:
Cannot find path 'C:\TEMP\_100804_135716\missing' because it does not exist.
At C:\TEMP\_100804_135716\test.ps1:5 char:15
+ Get-ChildItem <<<< missing
This technical info will be excluded:
+ CategoryInfo : ObjectNotFound: (C:\TEMP\_100804_135716\missing:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
I took it a bit further because I didn't like the multilines from $error[0].InvocationInfo.PositionMessage.
Function FriendlyErrorString ($thisError) {
[string] $Return = $thisError.Exception
$Return += "`r`n"
$Return += "At line:" + $thisError.InvocationInfo.ScriptLineNumber
$Return += " char:" + $thisError.InvocationInfo.OffsetInLine
$Return += " For: " + $thisError.InvocationInfo.Line
Return $Return
}
[string] $ErrorString = FriendlyErrorString $Error[0]
$ErrorString
You can look at what else is availible to construct your own String via:
$Error | Get-Member
$Error[0].InvocationInfo | Get-Member
Foreach ($Errors in $Error){
#Log Eintrag wird zusammengesetzt und in errorlog.txt geschrieben
"[$Date] $($Errors.CategoryInfo.Category) $($Errors.CategoryInfo.Activity) $($Errors.CategoryInfo.Reason) $($Errors.CategoryInfo.TargetName) $($Errors.CategoryInfo.TargetType) $($Errors.Exception.Message)" |Add-Content $Path\errorlog.txt -Encoding UTF8
}
You can also do this and you will get all Informations about the Error
Similar to #tomasr, but shorter:
$($error[0])
For all errors in a script:
$($error)