Categories
Uncategorized

Pull users from AD

I needed:

  • users from AD with specific OU
  • non disabled
  • filter by department
  • manager details
  • last logon time and other details

For pulling active (non disabled) users belonging to specific group along with their managers name into CSV, I made following powershell script. Output is then loaded into excel and send automatically to managers for approval. Department “x” means a special user which will be omitted.

$FileName="c:\somepath\somefile.txt"

if (Test-Path $FileName) 
{
  Remove-Item $FileName
}

$fileEncoding = "Default"

Out-File -encoding $fileEncoding $FileName

$dn = (Get-ADGroup 'Some group').DistinguishedName
$users = Get-ADUser -Filter " memberof -RecursiveMatch '$dn'" -Properties $properties

Foreach ($User in $Users)
{
 if ($user.Enabled -and ($user.Department -ne "x")) {      
  $userName=$user.UserPrincipalName
  $ou=$user.DistinguishedName.split(',OU=')[5]
  $man=$user.Manager
  $mail=$user.mail
 
  if ($man -ne $null) {	  
	$mgrUsr=(Get-ADUser $man -Properties UserPrincipalName,DisplayName,mail)
	$mngr=$mgrUsr.UserPrincipalName + ";" +$mgrUsr.mail + ";" + $mgrUsr.DisplayName
  } else {
	$mngr=";;"  
  }
  ($user.UserPrincipalName + ";" +  $user.cn + ";" + $user.LastLogonDate + ";" + $ou + ";" + ";" + $mngr  + ";" + $user.Department)  | Out-File -encoding $fileEncoding $FileName -Append 
  
 } 
}

for VPS hosting go here:

Categories
Wordpress WP plugins

CJ feed content generator

This WordPress plugin can import product feeds in Google format which is (used by affiliate platforms like Commission Junction and others) and create whole affiliate website from it with few clicks.

It is really that simple as import a feed and then place shortcode on the frontpage or any other page to become your affiliate site.

Main features

  • import / bulk import even huge feed files
  • automatically generate categories with product counts
  • store products as custom posts+metas or in dedicated table (for lightning fast filtering)
  • internal caching system for even better performance
  • easy templating system for custom appearance
  • ajax powered loading more products (instead of pagination, next items are loaded when you scroll to the bottom like on Facebook)
  • ajax product filtering

Demos

Download

you can soon find downloadable plugin on wordpress plugin site, meanwhile, if you are interested, drop a comment below

Categories
Cheats and Scripts Tools

FOE tool

I made a tool for the game Forge of Empires that makes boring clicking for you. Check out the tool on this page:

Categories
Wordpress

Adding plugins to WP repo

Step 1.: create wp dev account at https://developer.wordpress.org/

Step 2.: prepare nice readme.txt, have it checked with https://wordpress.org/plugins/developers/readme-validator/

Step 3.: pack it all together in a zip and submit using https://wordpress.org/plugins/developers/add/

Step 4.: wait for approval

Step 5.: upload using SVN to WP repo. Using Windows you can:

  • download tortoise svn check option to install command line tools
  • create a folder for your files
mkdir my-local-dir
  • download your files with
svn co http://svn.wp-plugins.org/your-plugin-name my-local-dir
  • put your files into trunk folder, then
svn add trunk/*
  • upload files into wp repo
svn ci -m 'my plugin release' --username yourusername --password yourpassword
  • getting error “plugin is not under version control?” So did I. All docs fails for Windows, you need to use double quotes instead of single quotes. so:
svn ci -m "my plugin release" --username yourusername --password yourpassword
  • should do the trick

Enjoy!

Categories
Wordpress WP plugins

WP custom read more image effect block

I have made this simple custom block option to Guttenberg editor with fancy image and a read more link.

Demo:

wp plugin url: https://wordpress.org/plugins/custom-read-more-image-effect-block

Categories
Wordpress

Deleting wordpress posts

Running wp_delete_post($postId,true); for every post could take serious amount of time. If you need to delete everything let’s say from post _id>320 and category equals to some_category, then this is much more faster solution:

(run mysql commands from phpmyadmin or somewhere,

DELETE from wp_posts WHERE ID>320
DELETE from wp_postmeta WHERE post_id>320
DELETE from wp_terms WHERE term_id>1
DELETE from wp_term_relationships WHERE object_id>320
DELETE from wp_term_taxonomy WHERE taxonomy like 'some_category'
Categories
Programming Tools

Anti-ransomware script solution

The idea behind this is simple- if we find out files are being changed quickly, we can still make steps to save much of valuable data from ransomware infection.

That’s why we create a “honeypot” with files likely to be encrypted by ransomware. On windows those have following extensions: doc, docx, jpg, png, xls, xlsx and txt. These files are made with a random content and placed to easily reachable places (meaning not buried deeply in directory structure). Also a ransomware usually goes through the file system structure in alphabetical order, so c:\afile\ would be likely to hit sooner than c:\wrong\dang\files\honeypot\something.

Anyway, now we have the honeypot files, we need to watch over them and as soon as they are changed send alert, disconnect network to prevent further infection or shutdown the computer.

We can solve this completely within a windows batch file with windows utilities involved (certutil.exe for generating md5 hashes and fc.exe for comparing them). A simple task in windows task scheduler runs the .bat in short intervals making the job done.

If you are interested, I am willing to explain more or even sell the code along with documentation.

I have also such application written in C# which runs in background- so no need to use task scheduler- so the emergency action happens immediately when files are enrypted.

Categories
Dynamics NAV / Navision

Dynamics NAV- fieldref

In case we need to import field programatically, without direct referencnig, there is a FieldRef in Navision.


setField(tabName : Text[30];fieldId : Integer;mVal : Text[1024])
IF fieldId < 1 THEN EXIT;
IF tabName = 'sometablename' THEN BEGIN
 greRecRef.GETTABLE(greNS); // get table reference
 greFieldRef:=greRecRef.FIELD(fieldId);
 IF FORMAT(greFieldRef.TYPE) = 'Boolean' THEN BEGIN
   IF (mVal = '1') OR (UPPERCASE(mVal) = 'YES') THEN greFieldRef.VALUE:=TRUE
   ELSE greFieldRef.VALUE:=FALSE;
 END ELSE IF (FORMAT(greFieldRef.TYPE) = 'Integer') OR (FORMAT(greFieldRef.TYPE) = 'Decimal') THEN BEGIN
   EVALUATE(mNum,mVal);
   greFieldRef.VALUE:=mNum;
 END ELSE IF (FORMAT(greFieldRef.TYPE) = 'Code') OR (FORMAT(greFieldRef.TYPE) = 'Text') THEN BEGIN
   greFieldRef.VALUE:=mVal;
 END ELSE IF (FORMAT(greFieldRef.TYPE) = 'Date') THEN BEGIN
   EVALUATE(mDate,mVal);
   greFieldRef.VALUE:=mDate;
 END ELSE IF (FORMAT(greFieldRef.TYPE) = 'Time') THEN BEGIN
   EVALUATE(mTime,mVal);
   greFieldRef.VALUE:=mTime;
 END ELSE ERROR('This field type is not yet covered.');
END;
Categories
Dynamics NAV / Navision

Dynamics NAV – writing logs

Something we need in every serious code object- writing logs to a logfile.

{
1)  open log file
}
OpenLogFile()

ltePath:=getMainPath('')+'csvlog.txt';

LogFile.TEXTMODE := TRUE;
LogFile.WRITEMODE(TRUE);
IF NOT LogFile.OPEN(ltePath) THEN
    IF NOT LogFile.CREATE(ltePath) THEN BEGIN
        EXIT; 
    END;
LogFile.SEEK(LogFile.LEN);
{
2) write text line
WriteLog(mess : Text[1000])
LogFile.WRITE(mess);
}
{
3) don't forget to close the file at the end
}
CloseLogFile()
LogFile.CLOSE();
Categories
Dynamics NAV / Navision

Dynamics NAV – Importing CSV files

I learned quite a lot during my 15 years working with Navision. I am going to share some of my precious knowledge here.

I’ll show how can we import a csv file into any NAV table, without any libraries or custom code units.

Importing CSV

Obvious part, which most of my code objects starts with:


Integer - OnPreDataItem()
Integer.SETRANGE(Number,1,1);

readCSV()
mFilePath := getMainPath('downloaded')+'RA_Hertz-DE.csv';

//invalid->ready

//downloaded->ready
lreFileRec.SETRANGE(Path, getMainPath(''));
lreFileRec.SETRANGE("Is a file", TRUE);
lreFileRec.SETFILTER(Name, '*.csv');
IF lreFileRec.FIND('-') THEN REPEAT
 lreNewCSVfile.TEXTMODE := FALSE;
 lreNewCSVfile.WRITEMODE(TRUE);
 IF NOT lreNewCSVfile.OPEN(getMainPath('ready') + '\' + lreFileRec.Name) THEN
     IF NOT lreNewCSVfile.CREATE(getMainPath('ready') + '\' + lreFileRec.Name) THEN
         ERROR('nejde vytvorit soubor');

 lreCSVfile.TEXTMODE := FALSE;
 lreCSVfile.OPEN(lreFileRec.Path + '\' + lreFileRec.Name);
 lreCSVfile.SEEK(0);
 REPEAT
  lreCSVfile.READ(mChar);
  IF mChar='"' THEN mChar := 0;
  IF mChar <> 0 THEN lreNewCSVfile.WRITE(mChar);
 UNTIL lreCSVfile.POS >= (lreCSVfile.LEN);
 lreCSVfile.CLOSE();
 lreNewCSVfile.CLOSE();
UNTIL (lreFileRec.NEXT() =0);

cacheCols();
cacheFields();

//import ready
lreFileRec.SETRANGE(Path, getMainPath('ready'));
lreFileRec.SETRANGE("Is a file", TRUE);
lreFileRec.SETFILTER(Name, '*.csv');
IF lreFileRec.FIND('-') THEN REPEAT
 x:=1;
 mImportFile.OPEN(lreFileRec.Path + '\' + lreFileRec.Name);
 mImportFile.CREATEINSTREAM(mImportStream);
 WHILE NOT mImportStream.EOS DO BEGIN
  mImportStream.READ(mChar);
  //nova radka
  IF mChar=13 THEN BEGIN
   processCSV(x);
   linCnt += 1;
   x:=1;
   CLEAR(gteVals);
  END;
  IF mChar=',' THEN x+=1;
  IF (mChar<>10) AND (mChar<>13) AND (mChar<>',') THEN BEGIN
   gteVals[x]:=gteVals[x] + FORMAT(mChar);
  END;
 END;
 mImportFile.CLOSE;
UNTIL lreFileRec.NEXT()=0;

//ready->imported
//ready->backup
{
 processing a CSV record. gteNAVfield/getNAVtab are arrays telling 1) which CSV fields we want to import and 2) to which fields/tables in NAV
}
processCSV(cnt : Integer)
greNS.INSERT(); // create new record

FOR n:=1 TO cnt DO BEGIN
 //find column name
 IF (gteNAVfield[n] <> '') AND (gteNAVfield[n] <> '?') THEN BEGIN
  lteColName:=gteNAVfield[n];
  lteTabName:=gteNAVtab[n];
  linFieldID:=getFieldID(lteTabName,lteColName);
  setField(lteTabName,linFieldID,gteVals[n]);
 END;
END;

greRecRef.SETTABLE(greNS); //save rec ref into the table
greNS.MODIFY();
{
 gets field id of a table by a field name
 gteNSfieldName is cached array of field names
 ginNSfieldID is cached array of field ids
}
getFieldID(tabName : Text[300];colName : Text[300]) fieldId : Integer
IF tabName = 'Some Table' THEN BEGIN
 FOR n:=1 TO ginRecFieldsCnt DO BEGIN
  IF gteNSfieldName[n] = colName THEN BEGIN
   fieldId:=ginNSfieldID[n]; //field id of NAV table
   EXIT;
  END;
 END;
END;
{
 greRecRef is variable of type RecordRef we point to greNS which is variable of type Record of chosen record
 greFieldRef is variable of type FieldRef which we use to reference to this record fields
}
//sets a field of a table with a value
setField(tabName : Text[30];fieldId : Integer;mVal : Text[1024])
IF fieldId < 1 THEN EXIT;
IF tabName = 'Some Table' THEN BEGIN
 greRecRef.GETTABLE(greNS); // get table reference
 greFieldRef:=greRecRef.FIELD(fieldId);
 greFieldRef.VALUE:=mVal;
END;
{
 after all fields are set, we call settable and modify to save loaded fields into Navision record
 greRecRef.SETTABLE(greNS); //save rec ref into the table
 greNS.MODIFY();
}

for more details about FieldRef and extensions for other FieldTypes, refer to https://cyltr.com/dynamics-nav-fieldref/