call powershell function with parameters - html

I am just getting started with Windows Powershell and I am try to create a function that parses a webpage. I have tested the individual calls in the function and they seem to be working correctly. Here is the function I have created.
function GoTo-Website ([string]website = "google.com")
{
$ie.navigate($website);
$image = #($ie.Document.getElementByName("main_image"))[0].href;
$title = #($ie.Document.getElementByTagName("h1"))[3].innerHTML;
$date = #($ie.Document.getElementByTagName("h3"))[0].innerHTML;
}
This is stored in powershellScript.ps1 in the current powershell directory.
The best error I can get when I call this function is
function goto-website "Website"
Missing function body in function declaration. At line:1 char:23 + function goto-website <<<< "website" + CategoryInfo : ParserError: (:) [], + FullyQualifiedErrorId : MissingFunctionBody
Is there anyway to modify my code to get pass this parser error?
I also was wondering if their is a way to call a function without putting "function" before the call?

Try this modified version of your code
function GoTo-Website
{
Param ($website)
$ie.navigate($website);
$image = #($ie.Document.getElementByName("main_image"))[0].href;
$title = #($ie.Document.getElementByTagName("h1"))[3].innerHTML;
$date = #($ie.Document.getElementByTagName("h3"))[0].innerHTML;
}
which you can call with
GoTo-Website "http://www.google.com"
or
GoTo-Website -website "http://www.google.com/"
No need to put "function" before the call.
See today's post on the Scripting Guy Blog for a little more information on functions.

After following advice on how to add parameters [and realizing I have to copy and paste my function into powershell] I was able to call my function. Here is the modified version of the function
function GoTo-Website
{ Param ($website)
$global:ie.navigate($website);
$global:image = #($ie.Document.getElementById("comic_image"))[0].href;
$global:title = #($ie.Document.getElementsByTagName("h1"))[3].innerHTML
$global:date = #($ie.Document.getElementsByTagName("h3"))[0].innerHTML;
}
I also had to change my parameters to global to expose the results and access an internet explorer variable that is activated.

Related

Parse JSON file uploaded in S3 using Lambda

I'm trying to parse a JSON file that get's uploaded in S3. I invoke the lambda function using an S3 PUT/POST method trigger.
I'm using the following code.. however i'm not able to parse the json file. Can someone please help me?
var aws = require('aws-sdk');
var s3 = new aws.S3();
exports.handler = async (event, context, callback) => {
var srcBucket = event.Records[0].s3.bucket.name;
var srcKey = event.Records[0].s3.object.key;
console.log("Params: srcBucket: " + srcBucket + " srcKey: " + srcKey + "\n");
var getParams = {
Bucket: srcBucket,
Key: srcKey,
};
s3.getObject(getParams, function (err, data) {
if (err) console.log(err, err.stack);
else {
console.log(JSON.stringify(data.Body.toString()));
}
});
};
Your code looks correct However, I'd suggest taking the example from AWS docs as your starting point. Since your Lambda handler is an async handler, you have to await the promise returned by s3.getObject() , otherwise your function will complete before the callback executes (see the example code from the link).
Since you mention that your Lambda function cannot parse the file, I assume the function gets invoked by S3 trigger (i.e. you can see the console.log('Params: ...) line in Cloudwatch Logs). If that's not the case, first check that the S3 trigger is configured correctly and S3 has permission to invoke the Lambda function. If you created the function via AWS Console, this permission would have been set automatically.
The next step I'd suggest is to check the Lambda function's IAM role. Check if the IAM role has s3:GetObject permission for your bucket and all objects under it or for the specific prefix you have configured S3 notification (e.g. <bucket>/* or <bucket>/prefix/*).
If the Lambda IAM permissions are correct, you'll have to check S3 bucket policies. I suspect you haven't set up bucket policies according to what you describe.

Why am I getting an undefined value when calling these scripts in Google App Maker?

I do not understand why when I am calling a ServerScript method from a ClientScript method, I am getting a value of undefined.
ClientScript:
function clientScript() {
var message;
message = google.script.run.test();
console.log("Message: " + message);
}
ServerScript:
function serverScript() {
return "hello";
}
I expected the console to print: Message: hello. However, I am getting this printed to my console: Message: undefined. Why am I getting an undefined value in my ClientScript method when I am returning a defined value in my ServerScript method? Thank you!
Because server calls are asynchronous. In order to handle server response you need to pass callback. Here is a snippet from Apps Script docs:
function onSuccess(numUnread) {
console.log(numUnread);
}
google.script.run.withSuccessHandler(onSuccess)
.getUnreadEmails();
Just in case AMs docs interpretation of the same thing - https://developers.google.com/appmaker/scripting/client#call_a_server_script

How to pass variable from module back to script?

I have noticed that variables inside a module function do not remain in scope after execution returns to the script. I came across Export-ModuleMember but that didn't seem to help, perhaps i'm using it wrong.
FunctionLibrary.psm1
Function AuthorizeAPI
{
# does a bunch of things to find $access_token
$access_token = "aerh137heuar7fhes732"
}
Write-Host $access_token
aerh137heuar7fhes732
Export-ModuleMember -Variable access_token -Function AuthorizeAPI
Main script
Import-Module FunctionLibrary
AuthorizeAPI # call to module function to get access_token
Write-Host $access_token
# nothing returns
I know as an alternative I could just dot source a separate script and that would allow me to get the access_token but I like the idea of using modules and having all my functions therein. Is this doable? Thanks SO!
As per #PetSerAl's comment, you can change the scope of your variable. Read up on scopes here. script scope did not work for me when running from console; global did.
$global:access_token = "aerh137heuar7fhes732"
Alternatively, you can return the value form the function it and store in a variable; no scope change needed.
Function
Function AuthorizeAPI
{
# does a bunch of things to find $access_token
$access_token = "aerh137heuar7fhes732"
return $access_token
}
Main Script
Import-Module FunctionLibrary
$this_access_token = AuthorizeAPI # call to module function to get access_token
Write-Host $this_access_token

cakephp 3.x _serialize key not working

I an trying to return json from a cakephp 3.1 controller function. My problem is that no matter what I do with the _serialize flag, the response is always that there is a missing view template file.
In the cake docs it says to set the _serialize flag if you do not need to use a template to format the response. Cake Docs on View _serialize
Below is the Javascript on the client side that initializes the process
function save_activity( mod, act, resp ) {
$.ajax({
method: 'POST',
url: '/activities/saveActivity',
data: {
'module' : "example1",
'activity_name' : "example2",
'response' : "example3"
},
dataType: 'json',
error: function( xhr, status, error ){
alert( status + error );
},
success: function( data, status, xhr ){
alert( status + data.success );
}
});
}
The Controller code that handles the json from the client.
public function saveActivity()
{
$user = $this->Auth->user();
//This line does not seem to do anything
//$this->request->input('json_decode', 'true');
//Debugger::log($this->request->data);
$activityTable = TableRegistry::get('Activities');
$activity = $activityTable->newEntity();
$activity->user_id = $user['id'];
$activity->module = $this->request->data('module');
$activity->activity_name = $this->request->data('activity_name');
$activity->response = $this->request->data('response');
//These lines do not have any effect
//$this->RequestHandler->renderAs($this, 'json');
//$this->response->type('application/json');
//$this->viewBuilder()->layout(null);
//$this->render(false);
$msg = '';
if ($activityTable->save($activity)) {
$msg = 'Activity Stored';
} else {
$msg = 'Activity Not Stored';
}
$this->set(['response' => $msg]);
//comment or uncomment this line and it makes no difference
//as it still returns a json response about a missing template.
$this->set('_serialize', true);
}
The error message I get when I include or remove the _serialize flag.
"Template file "Pages\json\module1\activity4.ctp" is missing."
Anyone have any insight into this mechanims? The workaround I have found is to include the template file... but this means I will have to generate a few dozen essentially empty template files to handle all the places this call is generated from.
Any help please?
Problem cause:- Violation of assumption.
My assumption was that the saveActivity method was being executed. While the reality was that AuthComponent was failing to allow access to that method and the default handler was being run instead, then the default view template was being looked for... and failing.
I found this by looking at the stack track attached to the error message in the returned page via devTools. I should also have verified this assumption with some simple trace logging calls. I already had the clue when I commented out the "$this->set('_serialize', true);" and nothing changed.
Then the simple solution was to authorise the method in the controllers beforeFilter:
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow('saveActivity');
$this->Auth->allow('getActivity');
$this->eventManager()->off($this->Csrf);
}
Thanks for the assist ndm.

JSON response using cfscript function

I have this code as a cffunction that works fine:
<cfcomponent extends="core.core">
<cffunction name="loadService" access="remote" returnformat="JSON">
<cfscript>
objResponse = '{"CONFIG":[["internal"],[ "success"]],"DATA":[["Message1"]]}';
</cfscript>
<cfreturn objResponse>
</cffunction>
</cfcomponent>
I am trying to convert it to a full cfscript function like this:
component extends="core.core"{
remote JSON function loadService(){
objResponse = '{"CONFIG":[["internal"],[ "success"]],"DATA":[["Message1"]]}';
SerializeJSON(objResponse);
return objResponse;
}
}
The first way returns JSON fine and I can process it with jQuery. The second one throws and error "The value returned from the loadService function is not of type JSON."
I have tried it with and without SerializeJSON and both ways throw that error. I have also tried it without specifying JSON in the function syntax. That does not throw an error but it does wrap wddxpacket info around it. This is what it looks like when I don't specify JSON:
<wddxPacket version='1.0'><header/><data><string>{"CONFIG":[["internal"],[ "success"]],"DATA":[["Message1"]]}</string></data></wddxPacket>
I am stuck on this. Any help would be great. Thanks!
The correct CFScript syntax in CF9 is:
remote any function loadService() returnformat="JSON" {
Technically, "JSON" is not a valid returntype from a function (see here for all returntypes), but when you write:
remote JSON function
...you're basically saying that.
Notice in your tag-based cffunction call, you do not specify a returnType...so guess what it is by default? (hint: any).
It's easy to mix returnType and returnFormat up. A simple adjustment above and you should be good to go.
Complete Code
component extends="core.core" {
remote any function loadService() returnFormat="JSON" {
objResponse = '{"CONFIG":[["internal"],[ "success"]],"DATA":[["Message1"]]}';
SerializeJSON(objResponse);
return objResponse;
}
}
Also, I noticed that you have
SerializeJSON(objResponse);
in your function. This line has no effect on your function's return. So, it can easily be ommitted as your objResponse value is already in a JSON string. But, if the value of objResponse was something like
objResponse = {
"CONFIG" = [["internal"], ["success"]],
"DATA" = [["Message1"]]
};
then you could have done something like
return serializeJSON(objResponse);
which would have turn the complex data you had into a JSON string.
Here's the complete function
remote any function loadService()
returnFormat="JSON"
{
objResponse = {
"CONFIG" = [["internal"], ["success"]],
"DATA" = [["Message1"]]
};
return serializeJSON(objResponse);
}
Another way to specify the 'returnFormat' would be to use annotations:
component extends="core.core" {
/**
* #hint loads properties of an object and returns them in as JSON
* #output false
* #returnFormat JSON
*/
remote struct function loadService() {
objResponse = {
CONFIG = [["internal"],[ "success"]],
DATA = [["Message1"]]
};
return objResponse;
}
}