**Problem I am trying to solve: **
We want to be notified whenever one of our kiosk machines restart due to a Windows Update, so we can remotely connect right away and reset them to the desired state.
After trying different options (i.e. send email via SMTP triggered by an event via Task Scheduler, which proved unreliable due to script taking too long before restart occurs), this is the next attempted solution (perhaps it occurs faster?).
**Current solution attempted: **
Write data to a GoogleSheet via PowerShell script (below), triggered via Task Scheduler when a specific event occurs (i.e. Event Id: 1074). From there, GoogleSheet can easily send us the notification we want using Apps Script (details not relevant for this post).
Import-Module UMN-Google
# Set security protocol to TLS 1.2 to avoid TLS errors
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Google API Authozation
$scope = "https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file"
$certPath = "C:/Scripts/GoogleService/my-cert-path.p12"
$iss = 'name#projectname.iam.gserviceaccount.com'
$certPswd = 'mypassword'
try {
$accessToken = Get-GOAuthTokenService -scope $scope -certPath $certPath -certPswd $certPswd -iss $iss
} catch {
$err = $_.Exception
$err | Select-Object -Property *
"Response: "
$err.Response
}
$accessToken
# Define the GoogleSheet and the target Sheet
$spreadSheetID = 'google-sheet-id-i-omitted-from-this-sample'
$sheetName = 'MachineActivityData'
$EventId = 1074
$A = Get-WinEvent -MaxEvents 1 -FilterHashTable #{Logname = "System" ; ID = $EventId }
$Message = $A.Message
$EventID = $A.Id
$MachineName = $A.MachineName
$Source = $A.ProviderName
# Set the arrayValues
$arrayValues = #($MachineName, $Source, $EventId)
$appendValue = 'Append'
# Write to GoogleSheet (appending data)
Set-GSheetData -accessToken $accessToken -append $appendValue -sheetName $sheetName -spreadSheetID $spreadSheetID -values $arrayValues
Issue encontered:
When running the above script, I get the following error:
Set-GSheetData : A positional parameter cannot be found that accepts argument 'Append'.
At C:\Scripts\script_GoogleSheetConnection.ps1:40 char:1
+ Set-GSheetData -accessToken $accessToken -append $appendValue -sheetN ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Set-GSheetData], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Set-GSheetData
As you can see, I am using UMN-Google. This documentation helps, but I couldn't find much more than this to help with this error.
This error has something to do with the -append value not being correct.
Per the linked documentation, it appears to be a string (as in the example, and function definition). But I tried other options as well (i.e. bool...).
Any idea why the function Set-GSheetData is not accepting this parameter?
Quick note, I am fairly new to using PowerShell. I appreciate any suggestions.
Thank you kindly,
I tried the above script, and expected data to be appended to the specified GoogleSheet. However, the function Set-GSheetData returned an error, as a parameter is invalid. Per documentation, the parameter I entered is correct.
Related
When I run the following script to create a Scheduled Task, I receive the error
Bad type(Exception de HRESULT : 0x80020005 (DISP_E_TYPEMISMATCH))
$u = "domain\$env:username"
$p = "SomePassword"
$UserPass = ConvertTo-SecureString $p -AsPlainText -Force
$TaskName = "ML"
$TaskDescr = "Descriptor"
$TaskCommand = "$pos\$nm"
$TaskStartTime = [datetime]::Now.AddMinutes(5)
$service = new-object -ComObject("Schedule.Service")
$service.Connect()
$rtFr = $service.GetFolder("\")
$TaskDefinition = $service.NewTask(0)
$TaskDefinition.RegistrationInfo.Description = "$TaskDescr"
$TaskDefinition.Settings.Enabled = $true
$TaskDefinition.Settings.AllowDemandStart = $true
$triggers = $TaskDefinition.Triggers
$dd = "T"
$vv = "yyyy-MM-dd"
$xx = "HH:mm:ss"
$pr = "$vv$dd$xx"
$trigger = $triggers.Create(9)
$trigger.StartBoundary = $TaskStartTime.ToString($pr)
$trigger.Enabled = $true
$Action = $TaskDefinition.Actions.Create(0)
$action.Path = "$TaskCommand"
$rtFr.RegisterTaskDefinition("$TaskName",$TaskDefinition,6,$u,$UserPass,5)
There is too much to say about your script but let's focus on your issue:
Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)
This error is caused by the fact that $rtFr.RegisterTaskDefinition parameter for the password requires clear text, not encrypted string. So change your script as follow:
Use $p instead of $UserPass
Change trigger type from 9 to 1 (see below why)
Change logon type from 5 to 6 (see below why)
Modifications:
# Change these lines
$trigger = $triggers.Create(9)
$rtFr.RegisterTaskDefinition("$TaskName",$TaskDefinition,6,$u,$UserPass,5)
# To this
$trigger = $triggers.Create(1)
$rtFr.RegisterTaskDefinition($TaskName,$TaskDefinition,6,$u,$p,6)
refs:
https://learn.microsoft.com/en-us/windows/win32/taskschd/taskfolder-registertaskdefinition
https://learn.microsoft.com/en-us/windows/win32/taskschd/triggercollection-create
This is enough for your script to be executed without errors
...
Now, if you don't change the trigger type from 9 to 1, you will encounter this error:
Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)
You are trying to create a task that will be executed at logon ($trigger = $triggers.Create(9)), which requires administrative privileges. So you must run your script from an elevated Powershell session (run as Administrator)
And finally, if you don't change the logon type from 5 to 6, you will encounter this error:
(XX,XX):UserId: At :XX char:XX
You are trying to create a task with a logon type TASK_LOGON_SERVICE_ACCOUNT, without specifying which service account to use. Also you are passing username and password parameters to create the task, they should be empty/null.
# Change this line
$rtFr.RegisterTaskDefinition($TaskName,$TaskDefinition,6,$u,$p,6)
# To this
$TaskDefinition.Principal.UserId = "S-1-5-18" # i.e Local System Account
$rtFr.RegisterTaskDefinition($TaskName,$TaskDefinition,6,$null,$null,5)
Conclusion:
So I don't know what you are trying to achieve but you must be consistent with all parameters for the task creation to execute properly.
I would advise you to use SCHTASKS.exe instead of the COM object, it will be easier, less complex and it's available on Windows 7 and higher versions.
I tried to copy the list from root to subsite using PowerShell like the code below, but when in execute there is an error like the picture below. what is missing from my code
Add-PSSnapin "Microsoft.SharePoint.PowerShell"
Set-ExecutionPolicy -ExecutionPolicy "Unrestricted" -Force
$site= new-object Microsoft.SharePoint.SPSite("http://Sharepointroot")
$web = $site.Openweb()
$listroot = $web.Lists["Meeting Room Book"]
$itemsroot = $listroot.items
$siteapps = Get-SPWeb -Identity "http://sharepointroot/Apps"
$listapps = $siteapps.Lists["Meeting Room History"]
$i = 0
foreach ($item in $itemsroot) {
$i++
write-host -foregroundcolor yellow $i
$newitem= $listapps.Items.Add()
$newitem["Title"] = $item["Title"]
$newitem["Booking_x0020_Date"] = $item["Booking_x0020_Date"]
$newitem["End_x0020_Time"] = $item["End_x0020_Time"]
$newitem["Booked_x0020_By"] = $item["Booked_x0020_By"]
$newitem["Display"] = $item["Display"]
$newitem["Category"] = $item["Category"]
$newitem["Status"] = $item["Status"]
$newitem["Recurrence"] = $item["Recurrence"]
$newitem["Meeting_x0020_Title"] = $item["Meeting_x0020_Title"]
$newitem["BB"] = $item["BB"]
$newitem.update()
}
$web.dispose
$site.dispose
start-sleep 10
and I have error like below.
You cannot call a method on a null-valued expression.
at line:5 char:1
+ $newitem= $listapps.Items.Add()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+CategoryInfo : InvalidOperation: (:) [],RuntimeException
+FullyUalifiedErrorID : NullArray
Edit:
for this case closed because of an error in me, the name of the list that is made is not the same. thank you for responding to my question.
for code copy list to another subsite its work
To my understanding, this error means the script is attempting to do something, but another part of the script does not have any information to permit the first part of the script to work properly. In this case, $TargetItem .
I am attempting to publish a new Lambda function if it doesn't already exist. The Update seems to be working great, and I can update it at will. However when I try to do the Publish command I keep getting the error Member must not be null
$zipFilePath = "E:\ProductName-Dev\release.zip"
$zipFileItem = Get-Item -Path $zipFilePath
$fileStream = $zipFileItem.OpenRead()
$memoryStream = New-Object System.IO.MemoryStream
$fileStream.CopyTo($memoryStream)
$cmdOutput = Get-LMFunction -FunctionName new-extract;
try{
if($?) {
"lambda function already in AWS"
Update-LMFunctionCode -FunctionName new-extract -ZipFile $memoryStream -Publish 1
} else {
"need to publish new lambda function"
Publish-LMFunction -FunctionName new-extract -FunctionZip $zipFilePath -Handler exports.handler -Role arn:aws:iam::0000000:role/my-extract -Region us-east-1
}
}
finally {
$fileStream.Close()
}
If I run the Publish-LMFunction without all of the parameters and enter things manually I still get the error. Is there something obvious I'm messing? I believe I have all 4 required fields added to my Publish function. I can also create these within the webconsole, so I don't think it's a credentials issue.
I was simply missing the Runtime parameter
Publish-LMFunction -FunctionName $FunctionName -FunctionZip $zipFilePath -Handler exports.handler -Role arn:aws:iam:$AccountNumber:role/$RoleName -Region $Region -Runtime nodejs4.3
Their documentation shows it as required but when you are writing in the Powershell ISE it does not put an asterisk by the field.
Apologies, I'm incredibly new to PowerShell (And scripting in general), and I'm having a problem with the very basics of IE Automation that I can't quite get my head round.
What I want to do is have a script that automatically logs onto a webpage, and then inputs data into a form. But I can't seem to input data into the text input fields on the login page. I've been scouring the internet left right and centre, but haven't yet found the answer, though I imagine it will be an obvious one.
Here is my script so far:
$ie = new-object -ComObject InternetExplorer.Application;
$requestUri = "www.testurl.com"
$ie.visible = $true
$ie.navigate($requestUri)
while ($ie.ReadyState -ne 4)
{
start-sleep -Seconds 1;
}
$doc = $ie.Document
$doc.GetElementById("ppm_login_username") = $userName
$userName.value = "UserName"
However, whenever I run the script, I get the error
The property 'value' cannot be found on this object. Verify that the property exists and can be set.
+ $userName.value = "UserName"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : PropertyNotFound
I have no experience with a lot of this, so again, apologies for using incorrect terminology.
Using the DOM explorer, the input field has the following line of code:
<INPUT id=ppm_login_username maxLength=240 size=40 name=userName>
So I'm confident that I'm getting the correct object, but it doesn't seem to accept the 'value' method when trying to pass data through to it.
Value does show up as a property of the object though, so I can't understand why it doesn't pass through.
Any help and time you can offer is greatly appreciated!
You've mixed it up. It should be $variable = value. Try:
$doc = $ie.Document
#Set $username to reference of "ppm_logon_username"-input node
$userName = $doc.GetElementById("ppm_login_username")
$userName.value = "UserName"
Where is the variable $userName defined?
It needs to have the property "value".
Usually you could add it like this:
$Username | Add-Member -MemberType NoteProperty -Value "UserName" -Name value
but I am not sure whether this is possible for a variable of the type string.
I am not sure why you are trying to set $userName.value = "UserName" anyway.
Additionally it might be better to just use Invoke-WebRequest / Invoke-RestMethod, instead of trying to automate IE :)
https://technet.microsoft.com/de-de/library/hh849901.aspx
https://technet.microsoft.com/en-us/library/hh849971(v=wps.620).aspx
When attempting to access a network shared folder, DSC returns an "Access is denied" error, despite that I have provided a valid credential to it.
I'm using a DSC configuration, where a DSC "Script" resource is as follows:
Script myScriptResource {
GetScript = {return $true}
SetScript = {
$setupShare = '\\SomeNetworkSharesFolder\subFolder'
# This line produces valid results when run directly on node VM.
$build = Get-ChildItem "FileSystem::$setupShare" -Name | Sort-Object -Descending | Select-Object -First 1 | Out-String
Write-Host "Final Build: $build"
}
TestScript = {return $false} #Always run Set-Script block!
Credential = $ValidNetworkShareCredential
PsDscRunAsCredential = $ValidNetworkShareCredential
}
I receive an error:
VERBOSE: [MyNodeVM]: [[Script]myScriptResource] Performing the operation "Set-TargetResource" on target "Executing t
he SetScript with the user supplied credential".
Access is denied
+ CategoryInfo : PermissionDenied: (\\SomeNetworkSharesFolder\subFolder:) [], CimException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : myNodeVM
This might be due to the fact the LCM on the node VM is using a local SYSTEM user credential by default.
I attempted to change the user credential manually by navigating to the windows services manager (Hint: RUN then services.msc), and change the user credential in the logon tab of winRM service properties. Everytime I attempt to run the Windows Remote Management (WS-Managment) service, I receive and error:
Windows could not start the Windows Remote Management (WS-Management) service on Local Computer.
Error 1079: The account specified for this service is different from the account specified for other services running in the same process.
I don't know how to change the credential of LCM so that it can access the network shared folder upon the execution of Get-ChildItem.
Script myScriptResource {
GetScript = {return $true}
SetScript = {
$username ="someusername"
$secpasswd = ConvertTo-SecureString “somepassword” -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($username, $secpasswd)
$setupShare = '\\SomeNetworkSharesFolder\subFolder'
$psDriveArgs = #{ Name = ([guid]::NewGuid()); PSProvider = "FileSystem"; Root = $setupShare; Scope = "Private"; Credential = $mycreds }
new-psdrive #psDriveArgs -ErrorAction Stop
# This line produces valid results when run directly on node VM.
$build = Get-ChildItem "FileSystem::$setupShare" | Sort-Object -Descending | Select-Object -First 1 | Out-String
Write-Host "Final Build: $build"
}
TestScript = {return $false} #Always run Set-Script block!
}
There isn't an easy way to make it work with script resource because you need an ability to pass credentials to the script resource so that you can mount a drive and use it to copy/paste. If you want to copy files/directory from the share you can use 'File' resource. If you want to copy files/directory to the share you can use 'xFileUpload' resource from xPsDesiredStateConfiguration (https://gallery.technet.microsoft.com/xPSDesiredStateConfiguratio-417dc71d) Module. If you really need to use script resource to do this job, look into how xFileUpload resource is doing it.