Puling a value from a Text file in Powershell - powershell

I have a script that is supposed to reach out to a server and update a value for a user. Right now I can get that script to do it for a single user but I am trying to get it so that it will do it for multiple users from a text file. The script has three functions, the first creates the connection to the server, the second search for the user, and pulls the users GUID from the server's database, and the third set the user's value.
I have tried to update the getuser function so that it pulls the user data from a text file using get-content and then for foreach-object but when I run the script it continues to ask for an email address then errors out.
Here are the snippets from the getuser and the main functions. If anyone has any suggestion I would greatly appreciate it.
function getUser($email)
{
$methodName = "getUser()";
enterMethod($methodName);
$response = $null;
<# Create and set the headers for the REST request #>
$headers = #{}
$headers.add("Authorization", $global:authString);
$headers.add("Content-Type", "application/vnd.blackberry.users-v1+json");
$request = $global:uemBaseUrl + "/users?query=emailAddress=" + $email;
# Invoke RESTMethod to call users API to obtain users in the system
try
{
$response = Invoke-RestMethod -Method GET -Headers $headers -Uri $request;
if (($response.users -ne $null) -and ($response.users.length -eq 1))
{
Write-Host([string]::Format("User with email address '{0}' was found", $email));
}
else
{
Write-Host([string]::Format("User with email address '{0}' not found", $email));
exit(1);
}
}
catch
{
handleError $_;
}
exitMethod($methodName);
return $response;
}
function main
{
$methodName = "main()";
enterMethod($methodName);
try
{
if (setup)
{
$getUserResponse = get-content .\users.txt $emailaddress;
$getUserResponse = ForEach-Object
$userGUID = $getUserResponse.users.guid;
if($actionType -eq "Set")
{
if([string]::IsNullOrEmpty($expiry))
{
throw [System.ArgumentNullException]"The expiry argument is required when actionType=Set";
}
if(setActivationpassword($userGUID))
{
Write-Host([string]::Format("Random activation password has been set for user '{0}'", $emailAddress));
}
}
elseif($actionType -eq "ReplaceAll")
{
if([string]::IsNullOrEmpty($expiry))
{
throw [System.ArgumentNullException]"The expiry argument is required when actionType=ReplaceAll";
}
if(replaceActivationpassword($userGUID))
{
Write-Host([string]::Format("Activation password has been replaced for user '{0}'. Existing passwords have been expired.", $emailAddress ));
}
}
elseif($actionType -eq "ExpireAll")
{
if(expireActivationpasswords($userGUID))
{
Write-Host([string]::Format("All activation passwords expired for user '{0}'", $emailAddress));
}
}
}
}
catch
{
handleError $_;
}
exitMethod($methodName);
Write-Host("Complete!");
exit(0);
}
EDIT:
Here is the full working Script. This script allows you to do one user at a time.
<#
.DESCRIPTION
Authenticate and call either "Set", "Expire all" or "Replace" activation passwords for user BWS REST API depending what actionType is used.
.PARAMETER uemHostAndPort
Host and port of the UEM.
.PARAMETER tenantGuid
tenantGuid to use for authentication.
.PARAMETER authType
Authentication type to use. (Local or AD).
.PARAMETER username
username to use for authentication.
.PARAMETER password
password to use for authentication.
.PARAMETER domain
domain to use for authentication if authType=AD.
.PARAMETER actionType
Action to perform. (Set, ExpireAll or ReplaceAll)
.PARAMETER emailAddress
Email address of the user to perform the action on.
.PARAMETER expiry
The date and time the activation password will expire in ISO-8601 format.
#>
Param(
[Parameter(
Mandatory=$true,
HelpMessage="UEM Host and port."
)]
[ValidateNotNullorEmpty()]
[string]$uemHostAndPort,
[Parameter(
Mandatory=$true,
HelpMessage="Tenant guid to authenticate with."
)]
[ValidateNotNullorEmpty()]
[string]$tenantGuid,
[Parameter(
Mandatory=$true,
HelpMessage="Choose (AD | Local) authType."
)]
[ValidateSet('AD', 'Local')]
[string]$authType,
[Parameter(
Mandatory=$true,
HelpMessage="Username to authenticate with."
)]
[ValidateNotNullorEmpty()]
[string]$username,
[Parameter(
Mandatory=$true,
HelpMessage="Password to authenticate with."
)]
[ValidateNotNullorEmpty()]
[string]$password,
[Parameter(
Mandatory=$false
)]
[string]$domain,
[Parameter(
Mandatory=$true,
HelpMessage="Choose (Set | ExpireAll | ReplaceAll) actionType."
)]
[ValidateSet('Set', 'ExpireAll', 'ReplaceAll')]
[string]$actionType,
[Parameter(
Mandatory=$true,
HelpMessage="User email address to add or remove from group."
)]
[string]$emailAddress,
[Parameter(
Mandatory=$false,
HelpMessage="The date and time the activation password will expire in ISO-8601 format."
)]
[string]$expiry
)
$global:authString = $null;
$global:uemBaseUrl = $null;
<#
* Generate authorization header required to perform the REST call.
*
* #return
* True if successful, false otherwise.
#>
function setup()
{
$methodName = "setup()";
enterMethod($methodName);
$provider = $null;
$global:uemBaseUrl = "https://" + $uemHostAndPort + "/" + $tenantGuid + "/api/v1";
# Create and set the headers for the REST request
$headers = #{}
$headers.add("Content-Type", "application/vnd.blackberry.authorizationrequest-v1+json")
# Create body for REST call
$body = #{}
$body.add("provider",$authType);
$body.add("username", $username);
$body.add("password", [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($password)));
if($authType -eq "AD")
{
if(-not($domain))
{
throw [System.ArgumentNullException]"The domain argument is required when authType=AD";
}
$body.add("domain", $domain);
}
$request = $global:uemBaseUrl + "/util/authorization";
# Invoke RESTMethod to call authorization route to generate the authorization headers
try
{
$response = Invoke-RestMethod -Method POST -Headers $headers -Uri $request -Body ($body | ConvertTo-Json);
$global:authString = $response
}
catch
{
handleError $_;
}
Write-Host([string]::Format("Authorization header string generated: {0}", $global:authString));
Write-Host("Setup Complete...");
exitMethod($methodName);
return $true;
}
<#
* Generate authorization header required to perform the REST call.
*
* #param email
* Email of the user to get.
* #return
* User that was found.
#>
function getUser($email)
{
$methodName = "getUser()";
enterMethod($methodName);
$response = $null;
<# Create and set the headers for the REST request #>
$headers = #{}
$headers.add("Authorization", $global:authString);
$headers.add("Content-Type", "application/vnd.blackberry.users-v1+json");
$request = $global:uemBaseUrl + "/users?query=emailAddress=" + $email;
# Invoke RESTMethod to call users API to obtain users in the system
try
{
$response = Invoke-RestMethod -Method GET -Headers $headers -Uri $request;
if (($response.users -ne $null) -and ($response.users.length -eq 1))
{
Write-Host([string]::Format("User with email address '{0}' was found", $email));
}
else
{
Write-Host([string]::Format("User with email address '{0}' not found", $email));
exit(1);
}
}
catch
{
handleError $_;
}
exitMethod($methodName);
return $response;
}
<#
* Set acctivation password for a user.
*
* #param userGuid
* Guid of user.
* #return
* True if successful, false otherwise.
#>
function setActivationpassword($userGuid)
{
$methodName = "setActivationpassword()";
enterMethod($methodName);
# Create and set the headers for the REST command
$headers = #{}
$headers.add("Authorization", $global:authString);
$headers.add("Content-Type", "application/vnd.blackberry.activationpasswords-v1+json");
# Create body for REST call
$body = #{};
$innerBody = #(#{
"password" = $null;
"emailTemplate" = $null;
"expiry" = $expiry;
"expireAfterUse" = "true";
"activationProfile"= $null;
});
$body.add("activationPasswords",$innerBody);
$request = $global:uemBaseUrl + "/users/" + $userGuid + "/activationPasswords";
# Invoke RESTMethod to set activation password.
try
{
$response = Invoke-RestMethod -Method POST -Headers $headers -Uri $request -Body ($body | ConvertTo-Json);
}
catch
{
handleError $_;
}
exitMethod($methodName);
return $true;
}
<#
* Expire all acctivation passwords for a user.
*
* #param userGuid
* Guid of user.
* #return
* True if successful, false otherwise.
#>
function expireActivationpasswords($userGuid)
{
$methodName = "expireActivationpasswords()";
enterMethod($methodName);
# Create and set the headers for the REST command
$headers = #{}
$headers.add("Authorization", $global:authString);
$headers.add("Content-Type", "application/vnd.blackberry.activationpasswords-v1+json");
$request = $global:uemBaseUrl + "/users/" + $userGuid + "/activationPasswords";
# Invoke RESTMethod to exipre all activation passwords.
try
{
$response = Invoke-RestMethod -Method DELETE -Headers $headers -Uri $request
}
catch
{
handleError $_;
}
exitMethod($methodName);
return $true;
}
<#
* Replace all acctivation passwords for a user.
*
* #param userGuid
* Guid of user.
* #return
* True if successful, false otherwise.
#>
function replaceActivationpassword($userGuid)
{
$methodName = "replaceActivationpassword()";
enterMethod($methodName);
# Create and set the headers for the REST command
$headers = #{}
$headers.add("Authorization", $global:authString);
$headers.add("Content-Type", "application/vnd.blackberry.activationpasswords-v1+json");
# Create body for REST call
$body = #{};
$innerBody = #(#{
"password" = $null;
"emailTemplate" = $null;
"expiry" = $expiry;
"expireAfterUse" = "true";
"activationProfile"= $null;
});
$body.add("activationPasswords",$innerBody);
$request = $global:uemBaseUrl + "/users/" + $userGuid + "/activationPasswords";
# Invoke RESTMethod to set activation password.
try
{
$response = Invoke-RestMethod -Method PUT -Headers $headers -Uri $request -Body ($body | ConvertTo-Json);
}
catch
{
handleError $_;
}
exitMethod($methodName);
return $true;
}
<#
* Logging for method entry.
*
* #param methodName
* Name of the method to log
#>
function enterMethod($methodName)
{
Write-Host([string]::Format("Entering {0}...", $methodName));
}
<#
* Logging for method exit.
*
* #param methodName
* Name of the method to log.
#>
function exitMethod($methodName)
{
Write-Host([string]::Format("Exiting {0}...", $methodName));
}
<#
* Handle any errors that occur when performing the REST call.
*
* #param error
* The group create context.
#>
function handleError($error)
{
Write-Error ("The command cound not be completed. `r`nReason: " + $error.exception.message + " `r`nDetails: "+ $error.errordetails);
exit(1);
}
function main
{
$methodName = "main()";
enterMethod($methodName);
try
{
if (setup)
{
$getUserResponse = getuser $emailaddress;
$userGUID = $getUserResponse.users.guid;
if($actionType -eq "Set")
{
if([string]::IsNullOrEmpty($expiry))
{
throw [System.ArgumentNullException]"The expiry argument is required when actionType=Set";
}
if(setActivationpassword($userGUID))
{
Write-Host([string]::Format("Random activation password has been set for user '{0}'", $emailAddress));
}
}
elseif($actionType -eq "ReplaceAll")
{
if([string]::IsNullOrEmpty($expiry))
{
throw [System.ArgumentNullException]"The expiry argument is required when actionType=ReplaceAll";
}
if(replaceActivationpassword($userGUID))
{
Write-Host([string]::Format("Activation password has been replaced for user '{0}'. Existing passwords have been expired.", $emailAddress ));
}
}
elseif($actionType -eq "ExpireAll")
{
if(expireActivationpasswords($userGUID))
{
Write-Host([string]::Format("All activation passwords expired for user '{0}'", $emailAddress));
}
}
}
}
catch
{
handleError $_;
}
exitMethod($methodName);
Write-Host("Complete!");
exit(0);
}
# Call main function.
main;

Your problem is most likely here:
$getUserResponse = get-content .\users.txt $emailaddress;
$getUserResponse = ForEach-Object
It's going to be hard to debug this without running it but what are you trying to do with this?:
$getUserResponse = get-content .\users.txt $emailaddress
$emailAddress from what I can see is a never defined. Is the users.txt just a line by line file full of users files?
ForEach-Object would also need data to be piped to.

Related

Parameter set cannot be resolved using the specified named parameters in powershell script

I want to use this powershell script to import and export platforms from cyberark. However, its showing this error:
Parameter set cannot be resolved using the specified named parameters.
+ CategoryInfo : InvalidArgument: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : AmbiguousParameterSet
I am not very not very fimilar with powershell yet. Could someone please help me out. I would really appricate it. I tried many changes but nothing is really happening. I need to fix this error as soon as possible. Please go through the code and give me solution to fix it.
param
(
[Parameter(Mandatory = $true, HelpMessage = "Please enter your PVWA address (For example: https://pvwa.mydomain.com/PasswordVault)")]
#[ValidateScript({Invoke-WebRequest -UseBasicParsing -DisableKeepAlive -Uri $_ -Method 'Head' -ErrorAction 'stop' -TimeoutSec 30})]
[Alias("url")]
[String]$PVWAURL,
[Parameter(Mandatory = $false, HelpMessage = "Enter the Authentication type (Default:CyberArk)")]
[ValidateSet("cyberark", "ldap", "radius")]
[String]$AuthType = "cyberark",
# Use this switch to Import a Platform
[Parameter(ParameterSetName = 'Import', Mandatory = $true)][switch]$Import,
# Use this switch to Export a Platform
[Parameter(ParameterSetName = 'Export', Mandatory = $true)][switch]$Export,
# Use this switch to Import a Platform using a file
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $true)][switch]$ImportFile,
# Use this switch to Export a Platform using a file
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true)][switch]$ExportFile,
[Parameter(ParameterSetName = 'ExportActive', Mandatory = $true)][switch]$ExportActive,
[Parameter(ParameterSetName = 'ExportAll', Mandatory = $true)][switch]$ExportAll,
[Parameter(ParameterSetName = 'Export', Mandatory = $true, HelpMessage = "Enter the platform ID to export")]
[Alias("id")]
[string]$PlatformID,
[Parameter(ParameterSetName = 'Import', Mandatory = $true, HelpMessage = "Enter the platform Zip path for import")]
[Parameter(ParameterSetName = 'Export', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $false, HelpMessage = "Enter the platform Zip path for import")]
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ExportActive', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[Parameter(ParameterSetName = 'ExportAll', Mandatory = $true, HelpMessage = "Enter the platform Zip path to export")]
[string]$PlatformZipPath,
# Use this to specify where file to read is
[Parameter(ParameterSetName = 'ImportFile', Mandatory = $true, HelpMessage = "Enter the import file path for import")]
[Parameter(ParameterSetName = 'ExportFile', Mandatory = $true, HelpMessage = "Enter the export file path for export")]
[string]$listFile,
[Parameter(Mandatory = $false)]
$creds,
# Use this switch to Disable SSL verification (NOT RECOMMENDED)
[Parameter(Mandatory = $false)]
[Switch]$DisableSSLVerify
)
# Global URLS
# -----------
$URL_PVWAAPI = $PVWAURL + "/api"
$URL_Authentication = $URL_PVWAAPI + "/auth"
$URL_Logon = $URL_Authentication + "/$AuthType/Logon"
$URL_Logoff = $URL_Authentication + "/Logoff"
# URL Methods
# -----------
$URL_GetPlatforms = $URL_PVWAAPI + "/Platforms"
$URL_PlatformDetails = $URL_PVWAAPI + "/Platforms/{0}"
$URL_ExportPlatforms = $URL_PVWAAPI + "/Platforms/{0}/Export"
$URL_ImportPlatforms = $URL_PVWAAPI + "/Platforms/Import"
# Initialize Script Variables
# ---------------------------
$rstusername = $rstpassword = ""
$logonToken = ""
#region Functions
Function Test-CommandExists {
Param ($command)
$oldPreference = $ErrorActionPreference
$ErrorActionPreference = 'stop'
try { if (Get-Command $command) { RETURN $true } }
Catch { Write-Host "$command does not exist"; RETURN $false }
Finally { $ErrorActionPreference = $oldPreference }
} #end function test-CommandExists
# #FUNCTION# ======================================================================================================================
# Name...........: Join-ExceptionMessage
# Description....: Formats exception messages
# Parameters.....: Exception
# Return Values..: Formatted String of Exception messages
# =================================================================================================================================
Function Join-ExceptionMessage {
<#
.SYNOPSIS
Formats exception messages
.DESCRIPTION
Formats exception messages
.PARAMETER Exception
The Exception object to format
#>
param(
[Exception]$e
)
Begin {
}
Process {
$msg = "Source:{0}; Message: {1}" -f $e.Source, $e.Message
while ($e.InnerException) {
$e = $e.InnerException
$msg += "`n`t->Source:{0}; Message: {1}" -f $e.Source, $e.Message
}
return $msg
}
End {
}
}
#endregion
Function import-platform {
param(
[string]$PlatformZipPath
)
If (Test-Path $PlatformZipPath) {
$zipContent = [System.IO.File]::ReadAllBytes($(Resolve-Path $PlatformZipPath))
$importBody = #{ ImportFile = $zipContent; } | ConvertTo-Json -Depth 3 -Compress
try {
$ImportPlatformResponse = Invoke-RestMethod -Method POST -Uri $URL_ImportPlatforms -Headers $logonHeader -ContentType "application/json" -TimeoutSec 2700 -Body $importBody
Write-Debug "Platform ID imported: $($ImportPlatformResponse.PlatformID)"
Write-Host "Retrieving Platform details"
# Get the Platform Name
$platformDetails = Invoke-RestMethod -Method Get -Uri $($URL_PlatformDetails -f $ImportPlatformResponse.PlatformID) -Headers $logonHeader -ContentType "application/json" -TimeoutSec 2700
If ($platformDetails) {
Write-Debug $platformDetails
Write-Host "$($platformDetails.Details.PolicyName) (ID: $($platformDetails.PlatformID)) was successfully imported and $(if($platformDetails.Active) { "Activated" } else { "Inactive" })"
Write-Host "Platform details:"
$platformDetails.Details | Select-Object PolicyID, AllowedSafes, AllowManualChange, PerformPeriodicChange, #{Name = 'AllowManualVerification'; Expression = { $_.VFAllowManualVerification } }, #{Name = 'PerformPeriodicVerification'; Expression = { $_.VFPerformPeriodicVerification } }, #{Name = 'AllowManualReconciliation'; Expression = { $_.RCAllowManualReconciliation } }, #{Name = 'PerformAutoReconcileWhenUnsynced'; Expression = { $_.RCAutomaticReconcileWhenUnsynched } }, PasswordLength, MinUpperCase, MinLowerCase, MinDigit, MinSpecial
}
} catch {
#Write-Error $_.Exception
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformZipPath"
""
}
}
} #end function Import
Function export-platform {
param(
[string]$PlatformID
)
try {
$exportURL = $URL_ExportPlatforms -f $PlatformID
Invoke-RestMethod -Method POST -Uri $exportURL -Headers $logonHeader -ContentType "application/zip" -TimeoutSec 2700 -OutFile "$PlatformZipPath\$PlatformID.zip" -ErrorAction SilentlyContinue
} catch {
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformID"
""
}
} #end function Import
Function Get-PlatformsList {
param(
[switch]$GetAll
)
$idList = #()
try {
If ($GetAll){
$url = $URL_GetPlatforms + "?PlatformType=Regular"
} else {
$url = $URL_GetPlatforms + "?Active=True&PlatformType=Regular"
}
$result = Invoke-RestMethod -Method GET -Uri $url -Headers $logonHeader -ErrorAction SilentlyContinue
foreach ($platform in $result.Platforms){
$idList += $platform.general.id
}
return $idList
} catch {
#Write-Error $_.Exception.Response
#Write-Error $_.Exception.Response.StatusDescription
($_.ErrorDetails | ConvertFrom-Json | Select-Object -Property ErrorMessage)
"Error while attempting to export $PlatformID"
""
}
} #end function Import
If (Test-CommandExists Invoke-RestMethod) {
If ($DisableSSLVerify) {
try {
Write-Warning "It is not Recommended to disable SSL verification" -WarningAction Inquire
# Using Proxy Default credentials if the Server needs Proxy credentials
[System.Net.WebRequest]::DefaultWebProxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials
# Using TLS 1.2 as security protocol verification
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 -bor [System.Net.SecurityProtocolType]::Tls11
# Disable SSL Verification
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $DisableSSLVerify }
} catch {
Write-Error "Could not change SSL validation"
Write-Error (Join-ExceptionMessage $_.Exception) -ErrorAction "SilentlyContinue"
return
}
} Else {
try {
Write-Debug "Setting script to use TLS 1.2"
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12
} catch {
Write-Error "Could not change SSL settings to use TLS 1.2"
Write-Error (Join-ExceptionMessage $_.Exception) -ErrorAction "SilentlyContinue"
}
}
# Check that the PVWA URL is OK
If ($PVWAURL -ne "") {
If ($PVWAURL.Substring($PVWAURL.Length - 1) -eq "/") {
$PVWAURL = $PVWAURL.Substring(0, $PVWAURL.Length - 1)
}
} else {
Write-Host -ForegroundColor Red "PVWA URL can not be empty"
return
}
Write-Host "Export / Import Platform: Script Started" -ForegroundColor Cyan
#region [Logon]
# Get Credentials to Login
# ------------------------
$caption = "Export / Import Platform"
$msg = "Enter your User name and Password";
if ($Null -eq $creds) {$creds = $Host.UI.PromptForCredential($caption, $msg, "", "")}
if ($null -ne $creds) {
$rstusername = $creds.username.Replace('\', '');
$rstpassword = $creds.GetNetworkCredential().password
} else { return }
# Create the POST Body for the Logon
# ----------------------------------
$logonBody = #{ username = $rstusername; password = $rstpassword; concurrentSession = 'true' }
$logonBody = $logonBody | ConvertTo-Json
try {
# Logon
$logonToken = Invoke-RestMethod -Method Post -Uri $URL_Logon -Body $logonBody -ContentType "application/json"
} catch {
Write-Host -ForegroundColor Red $_.Exception.Response.StatusDescription
$logonToken = ""
}
If ($logonToken -eq "") {
Write-Host -ForegroundColor Red "Logon Token is Empty - Cannot login"
return
}
# Create a Logon Token Header (This will be used through out all the script)
# ---------------------------
$logonHeader = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$logonHeader.Add("Authorization", $logonToken)
#endregion
switch ($PsCmdlet.ParameterSetName) {
"Import" {
import-platform $PlatformZipPath -error
}
"ImportFile" {
foreach ($line in Get-Content $listFile) {
Write-Debug "Trying to import $line"
if (![string]::IsNullOrEmpty($line)) { import-platform $line }
}
}
"Export" {
if (![string]::IsNullOrEmpty($PlatformID)) { export-platform $PlatformID}
}
"ExportFile" {
$null | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Force
foreach ($line in Get-Content $listFile) {
Write-Debug "Trying to export $line"
if (![string]::IsNullOrEmpty($line))
{
export-platform $line
("$PlatformZipPath\$line.zip").Replace("\\","\").Replace("/","\") | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Append
}
}
}
("ExportActive" -or "ExportAll") {
$platforms = Get-PlatformsList -GetAll:$(($PsCmdlet.ParameterSetName -eq "ExportAll"))
$null | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Force
foreach ($line in $platforms) {
Write-Debug "Trying to export $line"
if (![string]::IsNullOrEmpty($line)) {
export-platform $line
("$PlatformZipPath\$line.zip").Replace("\\","\").Replace("/","\") | Out-File -FilePath "$PlatformZipPath\_Exported.txt" -Append
}
}
}
}
# Logoff the session
# ------------------
Write-Host "Logoff Session..."
Invoke-RestMethod -Method Post -Uri $URL_Logoff -Headers $logonHeader -ContentType "application/json" | Out-Null
} else {
Write-Error "This script requires PowerShell version 3 or above"
}
Write-Host "Export / Import Platform: Script Finished" -ForegroundColor Cyan

How can I fill in a web form using PowerShell

I have a question about powershell, I have a script which allows me to connect to a secure url which asks me username and password, I manage to connect, and I receive as output an html file with entries, my question is how to fill in these inputs and submit ?
Explore the $o_response variable to check the return values. Call it by: fcn-check-site -UNAME username -UPASS password -URI secureURL
function fcn-check-site {
Param (
[ Parameter( Mandatory = $true ) ]
$UNAME,
[ Parameter( Mandatory = $true ) ]
$UPASS,
[ Parameter( Mandatory = $true ) ]
$URI
)
Begin {
$s_username = $UNAME
$s_password = $UPASS
$s_URI = $URI
}
Process {
try {
# Create a Web Request object. This object can have different properties/payloads attached to be sent to the URL in question.
$o_webrequest = [System.Net.WebRequest]::Create( $s_URI )
$o_secpasswd = $s_password | ConvertTo-SecureString -AsPlainText -Force -ErrorAction Stop
$o_mycreds = New-Object System.Management.Automation.PSCredential ($s_username,$o_secpasswd) -ErrorAction Stop
# The connection test is to check if the login returns a 'good/ok/200' value. Hence, nothing is POST-ed. Only GET-ted.
$o_webrequest.Method = 'GET'
$o_webrequest.Credentials = $o_mycreds
# 30 second timeout on the request to be made.
$o_webrequest.Timeout = 30000
# This C# code makes sure that SSL certificate checks are skipped.
try {
# This erroractionpreference variable will STOP the compilaton errors thrown by C#.
$ErrorActionPreference = 'Stop'
add-type -ErrorAction Stop -TypeDefinition #"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"#
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy -ErrorAction SilentlyContinue
$o_response = $o_webrequest.GetResponse()
if( ( $o_response.StatusCode -eq 'OK' ) -or `
( $o_response.StatusCode -eq 200 ) ) {
"$( $URI ) is accessible."
# Check the contents of $o_response to see what is returned.
}
else {
"$( $URI ) is NOT accessible. Response Status is : $( $o_response.StatusCode )"
}
}
catch {
"[ERROR] : $( $Error[ 0 ].ToString() )"
}
}
catch {
if( $Error[ 0 ].ToString() -match "Unable to connect to the remote server" ) {
"$( $URI ) is NOT accessible."
}
else {
"[ERROR] : $( $Error[ 0 ].ToString() )"
}
}
}
}

Automated Powerscript for creating github

Function jay {
[cmdletbinding(SupportsShouldProcess)]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "Enter the new repository name")]
[ValidateNotNullorEmpty()]
[string]$Name,
[string]$Description,
[switch]$Private,
[switch]$NoWiki,
[switch]$NoIssues,
[switch]$NoDownloads,
[switch]$AutoInitialize,
#license templates found at https://github.com/github/choosealicense.com/tree/gh-pages/_licenses
[ValidateSet("MIT", "apache-2.0", "gpl-3.0", "ms-pl", "unlicense")]
[string]$LicenseTemplate,
[Alias("token")]
[ValidateNotNullorEmpty()]
[string]$UserToken = 'github token here',
#write full native response to the pipeline
[switch]$Raw
)
Write-Verbose "[BEGIN ] Starting: $($MyInvocation.Mycommand)"
#display PSBoundparameters formatted nicely for Verbose output
[string]$pb = ($PSBoundParameters | Format-Table -AutoSize | Out-String).TrimEnd()
Write-Verbose "[BEGIN ] PSBoundparameters: `n$($pb.split("`n").Foreach({"$("`t"*2)$_"}) | Out-String) `n"
#create the header
$head = #{
Authorization = 'Basic ' + $UserToken
}
#create a hashtable from properties
$hash = #{
name = $Name
description = $Description
private = $Private -as [boolean]
has_wiki = (-Not $NoWiki)
has_issues = (-Not $NoIssues)
has_downloads = (-Not $NoDownloads)
auto_init = $AutoInitialize -as [boolean]
}
if ($LicenseTemplate) {
$hash.add("license_template", $LicenseTemplate)
}
$body = $hash | ConvertTo-Json
Write-Verbose "[PROCESS] Sending json"
Write-Verbose $body
#define parameter hashtable for Invoke-RestMethod
$paramHash = #{
Uri = "https://api.github.com/user/repos"
Method = "Post"
body = $body
ContentType = "application/json"
Headers = $head
UseBasicParsing = $True
DisableKeepAlive = $True
}
#should process
if ($PSCmdlet.ShouldProcess("$name [$description]")) {
$r = Invoke-RestMethod #paramHash
if ($r.id -AND $Raw) {
Write-Verbose "[PROCESS] Raw result"
$r
}
elseif ($r.id) {
write-Verbose "[PROCESS] Formatted results"
$r | Select-Object #{Name = "Name"; Expression = { $_.name } },
#{Name = "Description"; Expression = { $_.description } },
#{Name = "Private"; Expression = { $_.private } },
#{Name = "Issues"; Expression = { $_.has_issues } },
#{Name = "Wiki"; Expression = { $_.has_wiki } },
#{Name = "URL"; Expression = { $_.html_url } },
#{Name = "Clone"; Expression = { $_.clone_url } }
}
else {
Write-Warning "Something went wrong with this process"
}
if ($r.clone_url) {
$msg = #"
To push an existing local repository to Github run these commands:
-> git remote add origin $($r.clone_url)"
-> git push -u origin master
"#
Write-Host $msg -ForegroundColor Green
}
}
Write-Verbose "[END ] Ending: $($MyInvocation.Mycommand)"
}
I am working on this Powershell script to accept creating Github repo from my local pc to Github. But every time I try to enter description it fails and provides me this error. Could someone please help me out
Invoke-RestMethod : {"message":"Requires
authentication","documentation_url":"https://developer.github.com/v3/repos/#create"}
At C:\Users\norep\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:96 char:14
It looks like you're trying to use your Github API token with Basic Authentication, but according to the Github API v3 documentation that token is an OAuth token. Your header should look like this instead:
$head = #{
Authorization = 'token ' + $UserToken
}
You would use the Basic auth header if you were providing a base64 encoded string of your username and password (in the format of USERNAME:PASSWORD):
$basicAuthBytes = [System.Text.Encoding]::UTF8.GetBytes('USERNAME:PASSWORD')
$basicAuthBase64String = [Convert]::ToBase64String( $basicAuthBytes )
$head = #{
Authorization = "Basic ${basicAuthBase64String"
}

Is it possible to post media to twitter using Powershell?

I can't find any clue about it except a deprecated article using tweetpic which is now closed.
Any alternative that works in Powershell ?
Update: my question is not about if there is a Twitter API of course I know there is, but as it is not trivial to use like this Powershell Guy who is stuck https://twittercommunity.com/t/media-upload-doesnt-work-powershell/93861 I'm looking for a module.
Credit to Adam Bertram from https://www.adamtheautomator.com/twitter-module-powershell/.
Disclaimer: this only allows to post tweets and DM.
You can try using the PSM1 module below, but you need to create your own Twitter application on apps.twitter.com and generate an access token under the API keys section of the application. Once you do so, I recommend copying/pasting your API key, API secret, access token and access token secret as default parameters under the Get-OAuthAuthorization function.
<#
===========================================================================
Created on: 8/31/2014 3:11 PM
Created by: Adam Bertram
Filename: MyTwitter.psm1
------------------------------------------------------------------------
===========================================================================
#>
function Get-OAuthAuthorization {
<#
.SYNOPSIS
This function is used to setup all the appropriate security stuff needed to issue
API calls against Twitter's API. It has been tested with v1.1 of the API. It currently
includes support only for sending tweets from a single user account and to send DMs from
a single user account.
.EXAMPLE
Get-OAuthAuthorization -DmMessage 'hello' -HttpEndPoint 'https://api.twitter.com/1.1/direct_messages/new.json' -Username adam
This example gets the authorization string needed in the HTTP POST method to send a direct
message with the text 'hello' to the user 'adam'.
.EXAMPLE
Get-OAuthAuthorization -TweetMessage 'hello' -HttpEndPoint 'https://api.twitter.com/1.1/statuses/update.json'
This example gets the authorization string needed in the HTTP POST method to send out a tweet.
.PARAMETER HttpEndPoint
This is the URI that you must use to issue calls to the API.
.PARAMETER TweetMessage
Use this parameter if you're sending a tweet. This is the tweet's text.
.PARAMETER DmMessage
If you're sending a DM to someone, this is the DM's text.
.PARAMETER Username
If you're sending a DM to someone, this is the username you'll be sending to.
.PARAMETER ApiKey
The API key for the Twitter application you previously setup.
.PARAMETER ApiSecret
The API secret key for the Twitter application you previously setup.
.PARAMETER AccessToken
The access token that you generated within your Twitter application.
.PARAMETER
The access token secret that you generated within your Twitter application.
#>
[CmdletBinding(DefaultParameterSetName = 'None')]
[OutputType('System.Management.Automation.PSCustomObject')]
param (
[Parameter(Mandatory)]
[string]$HttpEndPoint,
[Parameter(Mandatory, ParameterSetName = 'NewTweet')]
[string]$TweetMessage,
[Parameter(Mandatory, ParameterSetName = 'DM')]
[string]$DmMessage,
[Parameter(Mandatory, ParameterSetName = 'DM')]
[string]$Username,
[Parameter()]
[string]$ApiKey = '2R3aJXohHmSABPaiQGaeprny7',
[Parameter()]
[string]$ApiSecret = '',
[Parameter()]
[string]$AccessToken = '',
[Parameter()]
[string]$AccessTokenSecret = ''
)
begin {
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
Set-StrictMode -Version Latest
try {
[Reflection.Assembly]::LoadWithPartialName("System.Security") | Out-Null
[Reflection.Assembly]::LoadWithPartialName("System.Net") | Out-Null
} catch {
Write-Error $_.Exception.Message
}
}
process {
try {
## Generate a random 32-byte string. I'm using the current time (in seconds) and appending 5 chars to the end to get to 32 bytes
## Base64 allows for an '=' but Twitter does not. If this is found, replace it with some alphanumeric character
$OauthNonce = [System.Convert]::ToBase64String(([System.Text.Encoding]::ASCII.GetBytes("$([System.DateTime]::Now.Ticks.ToString())12345"))).Replace('=', 'g')
Write-Verbose "Generated Oauth none string '$OauthNonce'"
## Find the total seconds since 1/1/1970 (epoch time)
$EpochTimeNow = [System.DateTime]::UtcNow - [System.DateTime]::ParseExact("01/01/1970", "dd/MM/yyyy", $null)
Write-Verbose "Generated epoch time '$EpochTimeNow'"
$OauthTimestamp = [System.Convert]::ToInt64($EpochTimeNow.TotalSeconds).ToString();
Write-Verbose "Generated Oauth timestamp '$OauthTimestamp'"
## Build the signature
$SignatureBase = "$([System.Uri]::EscapeDataString($HttpEndPoint))&"
$SignatureParams = #{
'oauth_consumer_key' = $ApiKey;
'oauth_nonce' = $OauthNonce;
'oauth_signature_method' = 'HMAC-SHA1';
'oauth_timestamp' = $OauthTimestamp;
'oauth_token' = $AccessToken;
'oauth_version' = '1.0';
}
if ($TweetMessage) {
$SignatureParams.status = $TweetMessage
} elseif ($DmMessage) {
$SignatureParams.screen_name = $Username
$SignatureParams.text = $DmMessage
}
## Create a string called $SignatureBase that joins all URL encoded 'Key=Value' elements with a &
## Remove the URL encoded & at the end and prepend the necessary 'POST&' verb to the front
$SignatureParams.GetEnumerator() | sort name | foreach {
Write-Verbose "Adding '$([System.Uri]::EscapeDataString(`"$($_.Key)=$($_.Value)&`"))' to signature string"
$SignatureBase += [System.Uri]::EscapeDataString("$($_.Key)=$($_.Value)&".Replace(',','%2C').Replace('!','%21'))
}
$SignatureBase = $SignatureBase.TrimEnd('%26')
$SignatureBase = 'POST&' + $SignatureBase
Write-Verbose "Base signature generated '$SignatureBase'"
## Create the hashed string from the base signature
$SignatureKey = [System.Uri]::EscapeDataString($ApiSecret) + "&" + [System.Uri]::EscapeDataString($AccessTokenSecret);
$hmacsha1 = new-object System.Security.Cryptography.HMACSHA1;
$hmacsha1.Key = [System.Text.Encoding]::ASCII.GetBytes($SignatureKey);
$OauthSignature = [System.Convert]::ToBase64String($hmacsha1.ComputeHash([System.Text.Encoding]::ASCII.GetBytes($SignatureBase)));
Write-Verbose "Using signature '$OauthSignature'"
## Build the authorization headers using most of the signature headers elements. This is joining all of the 'Key=Value' elements again
## and only URL encoding the Values this time while including non-URL encoded double quotes around each value
$AuthorizationParams = $SignatureParams
$AuthorizationParams.Add('oauth_signature', $OauthSignature)
## Remove any API call-specific params from the authorization params
$AuthorizationParams.Remove('status')
$AuthorizationParams.Remove('text')
$AuthorizationParams.Remove('screen_name')
$AuthorizationString = 'OAuth '
$AuthorizationParams.GetEnumerator() | sort name | foreach { $AuthorizationString += $_.Key + '="' + [System.Uri]::EscapeDataString($_.Value) + '", ' }
$AuthorizationString = $AuthorizationString.TrimEnd(', ')
Write-Verbose "Using authorization string '$AuthorizationString'"
$AuthorizationString
} catch {
Write-Error $_.Exception.Message
}
}
}
function Send-Tweet {
<#
.SYNOPSIS
This sends a tweet under a username.
.EXAMPLE
Send-Tweet -Message 'hello, world'
This example will send a tweet with the text 'hello, world'.
.PARAMETER Message
The text of the tweet.
#>
[CmdletBinding()]
[OutputType('System.Management.Automation.PSCustomObject')]
param (
[Parameter(Mandatory)]
[ValidateLength(1, 140)]
[string]$Message
)
process {
$HttpEndPoint = 'https://api.twitter.com/1.1/statuses/update.json'
$AuthorizationString = Get-OAuthAuthorization -TweetMessage $Message -HttpEndPoint $HttpEndPoint
## Convert the message to a Byte array
#$Body = [System.Text.Encoding]::ASCII.GetBytes("status=$Message");
$Body = "status=$Message"
Write-Verbose "Using POST body '$Body'"
Invoke-RestMethod -URI $HttpEndPoint -Method Post -Body $Body -Headers #{ 'Authorization' = $AuthorizationString } -ContentType "application/x-www-form-urlencoded"
}
}
function Send-TwitterDm {
<#
.SYNOPSIS
This sends a DM to another Twitter user. NOTE: You can only send up to
250 DMs in a 24 hour period.
.EXAMPLE
Send-TwitterDm -Message 'hello, Adam' -Username 'adam','bill'
This sends a DM with the text 'hello, Adam' to the username 'adam' and 'bill'
.PARAMETER Message
The text of the DM.
.PARAMETER Username
The username(s) you'd like to send the DM to.
#>
[CmdletBinding()]
[OutputType('System.Management.Automation.PSCustomObject')]
param (
[Parameter(Mandatory)]
[ValidateLength(1, 140)]
[string]$Message,
[Parameter(Mandatory)]
[string[]]$Username
)
process {
$HttpEndPoint = 'https://api.twitter.com/1.1/direct_messages/new.json'
## Convert the message to a Byte array
#$Message = [System.Uri]::EscapeDataString($Message)
foreach ($User in $Username) {
$AuthorizationString = Get-OAuthAuthorization -DmMessage $Message -HttpEndPoint $HttpEndPoint -Username $User -Verbose
$User = [System.Uri]::EscapeDataString($User)
$Body ="text=$Message&screen_name=$User"
Write-Verbose "Using POST body '$Body'"
Invoke-RestMethod -URI $HttpEndPoint -Method Post -Body $Body -Headers #{ 'Authorization' = $AuthorizationString } -ContentType "application/x-www-form-urlencoded"
}
}
}
Export-ModuleMember Send-Tweet
Export-ModuleMember Send-TwitterDm

PowerShell calling Sharepoint 2013 REST API update list item

After attempting several different examples I am unable to update list items using the Sharepoint REST API. I receive back a 400 error from the request.
The creplace is due to Sharepoint sending both ID and Id for some reason and breaking the ConvertFrom-Json in my Get-SPListItems method.
function Update-SPListItems
{
param
(
$listUpdate
)
$requestDigest = Get-RequestDigest
foreach($item in $listUpdate.Results)
{
$restUrl = $item.__metadata.uri
$item.tsFeedbackStatus = "Open"
$item.Modified = Get-Date -Format s
$updatedItem = $item | ConvertTo-Json
#convert back the duplicate field
$updatedItem = $updatedItem -creplace '"ignoreId":','"Id":'
$itemJsonBytes = [System.Text.Encoding]::ASCII.GetBytes($updatedItem)
try
{
#examples have shown POST/MERGE, POST/PATCH, MERGE/MERGE,
#PATCH/PATCH, none of them in those combinations have worked
$request = [System.Net.WebRequest]::Create($restUrl)
$request.Credentials = $Credential.GetNetworkCredential()
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$request.Headers.Add("If-Match", "*")
$request.Headers.Add("X-RequestDigest", $requestDigest)
$request.Headers.Add("X-HTTP-Method", "MERGE")
$request.Accept = "application/json;odata=verbose"
$request.Method = "POST"
$request.ContentType = "application/json;odata=verbose"
$request.ContentLength = $itemJsonBytes.Length
$stream = $request.GetRequestStream()
$stream.Write($itemJsonBytes, 0, $itemJsonBytes.Length)
$stream.Close()
$response = $request.GetResponse()
}
catch [System.Exception]
{
Write-Error $_.Exception.ToString()
}
}
}
Here is the exact error:
Update-SPListItems : System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at CallSite.Target(Closure , CallSite , Object )
At C:\Users\user\Desktop\SPListTest.ps1:120 char:11
$result = Update-SPListItems $list
~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Update-SPListItems
Try the below reusable function for this. It worked for me every time. Ensure to pass the parameters properly. This has authentication built into it and even works for older versions of PowerShell.
function Request-Rest{
[CmdletBinding()]
PARAM (
[Parameter(Mandatory=$False)]
[String]$Metadata,
[Parameter(Mandatory=$true)]
[String] $URL,
[Parameter(Mandatory=$False)]
[Switch]$listUpdate,
[Parameter(Mandatory=$False)]
[String]$RequestDigest,
[Parameter(Mandatory=$false)]
[Microsoft.SharePoint.Client.SharePointOnlineCredentials] $credentials,
[Parameter(Mandatory=$false)]
[String] $UserAgent = "PowerShell API Client",
[Parameter(Mandatory=$false)]
[Switch] $JSON,
[Parameter(Mandatory=$false)]
[Switch] $Raw
)
#Create a URI instance since the HttpWebRequest.Create Method will escape the URL by default.
#$URL = Fix-Url $Url
$URI = New-Object System.Uri($URL,$true)
#Create a request object using the URI
$request = [System.Net.HttpWebRequest]::Create($URI)
#Build up a User Agent
$request.UserAgent = $(
"{0} (PowerShell {1}; .NET CLR {2}; {3})" -f $UserAgent, $(if($Host.Version){$Host.Version}else{"1.0"}),
[Environment]::Version,
[Environment]::OSVersion.ToString().Replace("Microsoft Windows ", "Win")
)
if ($credentials -eq $null)
{
$request.UseDefaultCredentials = $true
}
else
{
$request.Credentials = $credentials
}
$request.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
#Request Method
$request.Method = "POST"
#Headers
if($listUpdate)
{
$request.Headers.Add("X-RequestDigest", $RequestDigest)
$request.Headers.Add("If-Match", "*")
$request.Headers.Add("X-HTTP-Method", "MERGE")
$request.ContentType = "application/json;odata=verbose"
$request.Accept = "application/json;odata=verbose"
}
#Request Body
if($Metadata) {
$Body = [byte[]][char[]]$Metadata
$request.ContentLength = $Body.Length
$stream = $request.GetRequestStream()
$stream.Write($Body, 0, $Body.Length)
}
else {
$request.ContentLength = 0
}
try
{
[System.Net.HttpWebResponse] $response = [System.Net.HttpWebResponse] $request.GetResponse()
}
catch
{
Throw "Exception occurred in $($MyInvocation.MyCommand): `n$($_.Exception.Message)"
}
$reader = [IO.StreamReader] $response.GetResponseStream()
if (($PSBoundParameters.ContainsKey('JSON')) -or ($PSBoundParameters.ContainsKey('Raw')))
{
$output = $reader.ReadToEnd()
}
else
{
$output = $reader.ReadToEnd()
}
$reader.Close()
if($output.StartsWith("<?xml"))
{
[xml]$outputXML = [xml]$output
}
else
{
[xml]$outputXML = [xml] ("<xml>" + $output + "</xml>")
}
Write-Output $outputXML
$response.Close()
}